我有一些文本,其中某些部分标有_{...}
;我需要用星号替换封闭的下划线和大括号对。因此,例如,Hello _{world} _{foo}
将变成Hello *world* *foo*
.
sed -r 's/_\{([^}]+)}/*\1*/g'
这是一个简单的问题,如果不是因为它们可以包含大括号转义符,就可以轻松解决。例如,文本:
Hello _{world \} \}} _{foo bar}
会导致:
Hello *world } }* *foo bar*
我该怎么做呢?
答案1
如果反斜杠表示“转义下一个字符”(无论是大括号、另一个反斜杠还是除行尾之外的任何字符),那么您可以“跳过”下一个字符,如下所示:
sed -r 's/_\{((\\.|[^}\\])+)\}/*\1*/g
如果反斜杠仅在大括号之前有特殊含义,那么您需要在每次运行 1 个或多个反斜杠后“跳过”第一个非反斜杠字符:
sed -r 's/_\{((\\+[^\]|[^}\\])+)\}/*\1*/g'
答案2
当您想要匹配前面没有的内容时,您需要负向后查找。sed
不支持前瞻和后顾,但 Perl 支持。
echo 'Hello _{world \} \}} _{foo bar}' | perl -npe 's/_\{(.+?)(?<!\\)}/*\1*/g'
这将输出:
Hello *world \} \}* *foo bar*