我正在使用GNU sed版本4.2.1,我正在尝试编写一个非贪婪的SED正则表达式来提取由另外两个字符串分隔的字符串。当分隔字符串是单字符时,这很容易:
s:{\([^}]*\)}:\1:g
在该示例中,字符串由' {'在左边和'}'在右边。
如果分隔字符串是多个字符,请说' {{{'和'}}}'我可以像这样调整上面的表达式:
s:{{{\([^}}}]*\)}}}:\1:g
所以中心表达式匹配任何不包含'}}}'关闭字符串。但这只适用于匹配字符串不包含'}'一点都不类似的东西:
{{{cannot match {this broken} example}}}
无效,但
{{{can match this example}}}
确实有效。当然
s:{{{\(.*\)}}}:\1:g
总是有效,但是贪婪,所以不适合在同一条线上出现多个模式的地方。
我理解[^a]
除了a
和[^ab]
之外的其他任何内容都意味着除了a
或b
以外的任何内容,所以,尽管它似乎有用,但我不知道#39; t认为[^}}}]
是排除3个连续字符序列的正确方法。
那么如何为SED编写一个匹配字符串的正则表达式,该字符串与另外两个字符串分隔?
答案 0 :(得分:1)
[^}}}]
不起作用是对的。否定的字符类匹配任何不是其中一个字符的内容。重复字符不会改变逻辑。所以你写的和[^}]
一样。 (当表达式中没有大括号时,很容易理解为什么会这样有效。)
在Perl和兼容的正则表达式中,您可以使用?
制作*
或+
非贪婪:
s:{{{(.*?)}}}:$1:g
这将始终与开场}}}
后的第一个{{{
匹配。
然而,this is not possible in Sed。事实上,我认为Sed没有办法做这场比赛。唯一的另一种方法是使用先行的高级功能,Sed也没有。
您可以使用-pe
选项以类似sed的方式轻松使用Perl,这会导致它从命令行(-e
)获取一行代码并自动遍历每一行并打印结果(-p
)。
perl -pe 's:{{{(.*?)}}}:$1:g'
用于就地编辑文件的-i
选项也很有用,但请确保您的正则表达式是正确的!
有关详细信息,请参阅perlrun。
答案 1 :(得分:0)
使用sed
,您可以执行以下操作:
sed -e :a -e 's/\(.*\){{{\(.*\)}}}/\1\2/ ; ta'
使用:
{{{can match this example}}} {{{can match this 2nd example}}}
这给出了:
can match this example can match this 2nd example
这不是懒惰的匹配,但是从右到左替换我们可以利用sed的贪婪。