我在GNU sed中使用前瞻性正则表达式有什么问题?

yeg*_*256 46 regex linux sed regex-lookarounds

这就是我正在做的(简化示例):

gsed -i -E 's/^(?!foo)(.*)$/bar\1/' file.txt
Run Code Online (Sandbox Code Playgroud)

我试图把bar每一行都放在前面foo.这是错误:

gsed: -e expression #1, char 22: Invalid preceding regular expression
Run Code Online (Sandbox Code Playgroud)

怎么了?

小智 118

sed -i '/^foo/! s/^/bar/' file.txt
Run Code Online (Sandbox Code Playgroud)
  • -i 将文件更改到位
  • /^foo/!仅对不!foo开头的行执行下一个操作 ^foo
  • s/^/bar/ 将行的开头更改为bar  

  • 这对于像^ foo`这样的锚定表达式来说很好,但不幸的是,它并没有延伸到模式中任何地方的负向前瞻的一般情况. (9认同)
  • 很好的解决方案.无需回溯.只需使用已有的功能. (6认同)
  • 然而,当行中仅存在一个替换实例时,它会扩展。例如, `'s/(?!foo)baz/bar/'` =>`'/foobaz/! s/baz/bar/'`。也许巧妙的适当应用可以将这种方法扩展到包含“foobaz baz”等的行。 (3认同)

Bir*_*rei 54

据我所知sed,既不前瞻也不后视.切换到具有类似语法的更强大的语言,例如perl.

  • 一个简单的`sed`到`perl`转换参考:`sed's/before/after/g'/ my/file` =>`cat/my/file | perl -ne's/before/after/g; 打印;'` (22认同)
  • @Batandwa将猫和管道用于perl是多余的.只需使用`perl -pi -e's/before/after/g'/ my/file`. (14认同)
  • 我认为这是一个错误的答案:正如 kkeller 的回答,“sed”具有提供多个编辑序列的功能。 (3认同)
  • 很遗憾没有前瞻。 (2认同)

hos*_*ter 7

您使用GNU sed不支持的perl兼容正则表达式(PCRE)语法.您应该根据SED Regular-Expressions重写您的正则表达式或使用perl.