替换正则表达式意外结果

Ook*_*key 2 sed

我试图取代关键字由大括号标示{}{date}{name}%@符号。为此,我使用{(.*?)\}正则表达式。

所以,我写了这个测试脚本:

echo "hello { welcome } and { welcome} home {friend } {(friend)}" | sed "s; {\(.*\?\)\}; %@; g"

output: hello %@
Run Code Online (Sandbox Code Playgroud)

但我期待着hello %@ and %@ home %@ %@结果。

更简单的替换工作完美:

echo "hello {} and {} home {} {}" | sed -e "s; {\}; %@; g"

output: hello %@ and %@ home %@ %@
Run Code Online (Sandbox Code Playgroud)

现在我被 0 个想法困住了如何解决这个问题。

Qua*_*odo 5

 {\(.*\?\)\}
Run Code Online (Sandbox Code Playgroud)

看到这.*是贪婪的,所以上面的正则表达式将从第一个{到最后一个匹配}。这证明了输出是合理的。

还要注意你没有对捕获组做任何事情\( \),所以它们可以被删除,最后一个大括号不需要转义。所以正则表达式可以改写成{.*\?}.

也许你的困惑是因为你习惯了 Perl 正则表达式?在 Perl 正则表达式中,.*?是非贪婪的,但sed不使用它们,它使用 BRE 基本正则表达式。

现在,要获得所需的输出,请执行

 {[^}]*}
Run Code Online (Sandbox Code Playgroud)

这将匹配大括号内的每个值,[^}]*表示“任意数量的非}字符”。

$ echo "hello { welcome } and { welcome} home {friend } {(friend)}" | 
  sed "s; {[^}]*}; %@; g"
hello %@ and %@ home %@ %@
Run Code Online (Sandbox Code Playgroud)