2012-10-01 16 views
1

我试图想出一个正则表达式搜索/替换来封装带有大括号(例如; ${foo})的变量(例如; $foo)。我想出了下面的正则表达式,但它并不如预期运行:在同一行中多次替换模式

s/"\([^"]*\)\$\([a-zA-Z0-9:]*\)\([^"]*\)"/"\1\${\2}\3"/g 

不过,我有一些问题,这种模式。它只会为每个引用的字符串执行一个模式。这是好的,因为我可以在文件上多次运行表达式,但它不处理已经封装在大括号中的变量。它只是把第二套大括号放在它们上面。

我现在的想法是剥离大括号\2,但我不认为这将工作,因为模式将仍然匹配,它将只执行每引号字符串1替换。我查看了反向引用表达式文档,但我无法确定更好的方法。

回答

3

尝试以下操作:

sed -e ':loop' -e 's/"\([^"]*\)\$\([a-zA-Z0-9:]\{1,\}\)\([^"]*\)"/"\1\${\2}\3"/' -e 't loop' 

这使得查找/替换成一个圈,这样它会反复尝试在每一行更换,直到没有更多的替代品可以做到的。

此操作,因为被处理时不存在要运行多个命令时,才会打印当前行,:loop创建一个名为loop标签,t loop返回执行到标号loop仅当有一个成功的替换。

正如在评论波东提到的,这个可以有多个报价行一些奇怪的行为,这里是应该在这些情况下正常工作的替代:

sed -e ':loop' -e 's/^\([^"]*\("[^"]*"[^"]*\)*\)"\([^"]*\)\$\([a-zA-Z0-9:]\{1,\}\)\([^"]*\)"/\1"\3\${\4}\5"/' -e 't loop' 
+0

太棒了,这与预期完全一致。谢谢。 – user1713098

+1

没问题,如果我的答案奏效,你可以[接受它](http://meta.stackexchange.com/a/5235),点击旁边复选标记的大纲。 –

+0

这只有在一行上只有一对'''',即数据如'a“b”$ c“d”'将以a结尾“a”b“$ {c}”d“ ' – potong

1

这可能会为你工作(GNU SED ):

echo 'a "$a" b $b "b $b b $b" $c c $c "$c c $c"' | 
sed 's/"\([^"]*\)"/"\n\1\n"/g;:a;s/\n\n//;ta;s/\n\$\([a-zA-Z0-9:]\+\)/${\1\}\n/;ta;s/\n\(.\)/\1\n/;ta' 
a "${a}" b $b "b ${b} b ${b}" $c c $c "${c} c ${c}" 
+0

有关多重报价问题的好消息。 –

相关问题