使用sed删除成对的大括号之间的所有内容

时间:2012-05-11 21:23:14

标签: regex sed

我有一个看起来像这样的字符串:

[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]

我想删除匹配%{...}的子字符串,这些子字符串可能包含也可能不包含相同顺序的其他子字符串。

我应该得到:[master *]作为最终输出。到目前为止我的进展:

gsed -E 's/%\{[^\}]*\}//g'

给出:

echo '[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]' | gsed -E 's/%\{[^\}]*\}//g'
[%}master %}*%B%F{green}%}]

因此,这适用于包含%{...}的{​​{1}}个部分。对%{...}之类的字符串失败(它返回%{%B%F{blue}%})。

我想要做的是解析字符串,直到找到匹配 %},然后删除所有内容,而不是删除}%{之间的所有内容第一次 }我遇到了。我不知道该怎么做。

我完全清楚可能有多种方法可以做到这一点;如果有可能的话,我更喜欢关于问题中指定方式的答案,但任何想法都非常受欢迎。

3 个答案:

答案 0 :(得分:1)

这可能对您有用:

echo '[%{%B%F{blue}%}master %{%F{red}%}*%{%f%k%b%}%{%f%k%b%K{black}%B%F{green}%}]' |
sed 's/%{/{/g;:a;s/{[^{}]*}//g;ta'
[master *]

答案 1 :(得分:0)

使用递归从内到外吃掉它。

s/%{.*?%}//g

然后换入

while(there's at least one more brace)

(可能是$?-ne 0 ...无论rcode使用什么来表示“没有匹配!”)

答案 2 :(得分:0)

试试这个:

sed -E 's/%{([^{}]*({[^}]*})*[^{}]*)*}//g'