从这样的模式
[string 1]{string 2}
我想提取string 2
之间的字符串最后的双匹配大括号——即删除[string 1]
以及打开{
和关闭}
。当or中存在额外的[
,]
对时,我下面的尝试就会失败。string 1
string 2
期望的输出:
下面脚本的所需输出以 开头foo
和结尾digit
:
foo bar 1
foo bar 2
foo[3]{xyz} bar 3
foo $sq[3]{xyz}$ bar 4
foo $sq[3]{xyz}$ bar 5
foo $sq[3]{xyz}$ bar 6
foo $sq[3]{xyz}$ bar 7
foo $sq[3]{xyz}$ bar 8'
foo $sq[abc]{xyz}$ bar 9'
foo $sq[abc]{xyz}$ bar 10'
假设:
- 参数为
RemoveInitialSquareBraces
总是以 a 开头[
,以 a 结束}
。 - 开幕
[
式为string 1
将要在的]
开头处有一个匹配。{
string 2
平台:
- 苹果系统 10.9.5
脚本
#!/bin/bash
function RemoveInitialSquareBraces {
#EXTRACTED_TEXT="$(\
# echo "$1" \
# | sed 's/^\[.*\]//' \
# | sed 's/{//' \
# | sed 's/}$//' \
# )"
EXTRACTED_TEXT="$(\
echo "$1" \
| sed 's/.*[^0-9]\]{\(.*\)}/\1/' \
)"
echo "${EXTRACTED_TEXT}"
}
RemoveInitialSquareBraces '[]{foo bar 1}'
RemoveInitialSquareBraces '[abc]{foo bar 2}'
RemoveInitialSquareBraces '[]{foo[3]{xyz} bar 3}'
RemoveInitialSquareBraces '[]{foo $sq[3]{xyz}$ bar 4}'
RemoveInitialSquareBraces '[goo{w}]{foo $sq[3]{xyz}$ bar 5}'
RemoveInitialSquareBraces '[goo[3]{w}]{foo $sq[3]{xyz}$ bar 6}'
RemoveInitialSquareBraces '[goo[3]{w} hoo[3]{5}]{foo $sq[3]{xyz}$ bar 7}'
RemoveInitialSquareBraces '[goo[3]{w} hoo[3]{5}]{foo $sq[3]{xyz}$ bar 8}'
RemoveInitialSquareBraces '[goo[3]{w} hoo[xyz]{5}]{foo $sq[abc]{xyz}$ bar 9}'
RemoveInitialSquareBraces '[goo[3]{w} hoo[xyz]{uvw}]{foo $sq[abc]{xyz}$ bar 10}'
exit 0
答案1
对于上面的输入示例,脚本可以是:
sed s/[^\"\']*[^0-9]\]{\(.*\)}/\1/ <<\END
"[]{foo bar 1}"
"[abc]{foo bar 2}"
"[]{foo[3]{xyz} bar 3}"
"[]{foo $sq[3]{xyz}$ bar 4}"
"[goo{w}]{foo $sq[3]{xyz}$ bar 5}"
"[goo[3]{w}]{foo $sq[3]{xyz}$ bar 6}"
"[goo[3]{w} hoo[3]{5}]{foo $sq[3]{xyz}$ bar 7}"
END
产生
"foo bar 1"
"foo bar 2"
"foo[3]{xyz} bar 3"
"foo $sq[3]{xyz}$ bar 4"
"foo $sq[3]{xyz}$ bar 5"
"foo $sq[3]{xyz}$ bar 6"
"foo $sq[3]{xyz}$ bar 7"
另一件事是你的功能可以简化:
function RemoveInitialSquareBraces {
printf '%s\n' "$@" |
sed ...
}
因此它将接受许多参数。
更新:对于更一般的情况,您可以分两步完成任务:
sed -e "
s/\[.*\[.*\][^[]*\]/[]/ #remove square brackets inside square brackets
s/\[[^]]*\]{\(.*\)\}/\1/ #lazy strip square brackets and curle brackets
"
添加:你可以使用perl-grep(带 perl 扩展的 GNU grep):
grep -Po '\[([^][]*\[\w+\][^][]*)*\]{\K.*(?=})'
或 sed 具有相同的正则表达式:
sed 's/\[\([^][]*\(\[\w\+\][^][]*\)*\)*\]{\(.*\)}/\3/'
答案2
这适用于您的输入:
sed -Ee's/.*(\{[^}]*(\{[^{}]*\}[^{]*)*\})/\1/'
{foo bar 1}'
{foo bar 2}'
{foo[3]{xyz} bar 3}'
{foo $sq[3]{xyz}$ bar 4}'
{foo $sq[3]{xyz}$ bar 5}'
{foo $sq[3]{xyz}$ bar 6}'
{foo $sq[3]{xyz}$ bar 7}'
{foo $sq[3]{xyz}$ bar 8}'
{foo $sq[abc]{xyz}$ bar 9}'
{foo $sq[abc]{xyz}$ bar 10}'
它只是删除匹配的卷曲对行中最后一次出现之前的所有内容,该行可能完全包含任意数量的其他匹配的卷曲对。