2012-05-11 30 views
4

我有一个字符串,它看起来像这样对大括号之间一切删除。使用sed

我应该得到:[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}%}] 

所以,这对于%{...}段里面做包含%{...}工作正常。它失败的字符串如%{%B%F{blue}%}(它返回%})。

我想要做的是分析该字符串,直到我找到匹配},然后卸下一切到这一点,而不是%{第一}我遇到之间消除一切。我不知道如何做到这一点。

我充分认识到,有可能是多种方式来做到这一点;如果可能的话,我更愿意回答关于问题中指定的方式,但任何想法都是值得欢迎的。

+1

正则表达式不适合匹配嵌套圆括号。嵌套括号不构成常规语言。 –

+0

实际上,你不能使用正则表达式来匹配嵌套的括号,可以匹配高达有越来越长的正则表达式数量有限,但你不能匹配arbitary数。我编写了一次代码生成器来匹配9层嵌套,这是你见过的最大的正则表达式,它不是非常高效的。 – Benj

+0

对于样本输入,预期输出和实际使用的代码+1。祝你好运。 – shellter

回答

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 *] 
+0

这很有魅力。如果没有太多的麻烦,你能否解释它是如何工作的? – simont

+0

首先用'{'替换所有'%{',然后删除所有内部的'{...}',如果成功则重复,直到不再。 – potong

0

使用递归来从内到外吃不出来。

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

while(there's at least one more brace) 

然后包(可能同时$ -ne 0 ...无论RCODE sed的用途说? “不匹配!”)

+0

我认为这是行不通的,因为终止模式是一个单独的'}'而不是'%}'。 – Jens

0

试试这个:

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