正则表达式预测grep中的"not follow by"

Lee*_*lla 92 regex grep regex-lookarounds

我试图为所有Ui\.未遵循Line或甚至只是信件的情况进行grepL

编写正则表达式以查找特定字符串的所有实例而不是其他字符串的正确方法是什么?

使用前瞻

grep "Ui\.(?!L)" *
bash: !L: event not found


grep "Ui\.(?!(Line))" *
nothing
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 136

负面的前瞻,你所追求的,需要比标准更强大的工具grep.您需要一个支持PCRE的grep.

如果你有GNU grep,目前的版本支持的选项-P或者--perl-regexp,然后你可以使用你想要的正则表达式.

如果你没有(一个足够新版本的)GNU grep,那么考虑一下ack.

  • 我很确定在这种情况下的问题只是在bash中你应该使用单引号而不是双引号,所以它不会将`!`视为特殊字符. (34认同)
  • 验证,正确的答案应该结合这个答案和@ NHDaly的评论.例如,该命令对我的作品:**的grep -P\*.*登录> '^*包含((but_not_this)?!)*$'. "d:\ TEMP\result.out"** (3认同)
  • 对于那些不支持-P的用户,请再次尝试将结果管道传递给grep --invert-match,例如:git log --diff-filter = D --summary | grep -E'删除。*?src'| grep -E --invert-match'xml'`。确保支持@Vinicius Ottoni的答案。 (2认同)

NHD*_*aly 36

部分问题的答案就在这里,而ack的行为方式相同: Ack和负向前瞻给出错误

您正在为grep使用双引号,这允许bash"解释!为历史扩展命令".

你需要在SINGLE-QUOTES中包装你的模式: grep 'Ui\.(?!L)' *

但是,请参阅@ JonathanLeffler的答案,以解决标准中负向前瞻的问题grep!


Kar*_*cek 8

您可能无法使用grep执行标准的负向前瞻,但通常您应该能够使用"反向"开关'-v'获得等效行为.使用它你可以构建一个正则表达式,以补充你想要匹配的东西,然后通过2个greps管道它.

对于有问题的正则表达式,你可能会做类似的事情

grep 'Ui\.' * | grep -v 'Ui\.L'
Run Code Online (Sandbox Code Playgroud)


dou*_*ine 5

If you need to use a regex implementation that doesn't support negative lookaheads and you don't mind matching extra character(s)*, then you can use negated character classes [^L], alternation |, and the end of string anchor $.

In your case grep 'Ui\.\([^L]\|$\)' * does the job.

  • Ui\. matches the string you're interested in

  • \([^L]\|$\) matches any single character other than L or it matches the end of the line: [^L] or $.

If you want to exclude more than just one character, then you just need to throw more alternation and negation at it. To find a not followed by bc:

grep 'a\(\([^b]\|$\)\|\(b\([^c]\|$\)\)\)' *

Which is either (a followed by not b or followed by the end of the line: a then [^b] or $) or (a followed by b which is either followed by not c or is followed by the end of the line: a then b, then [^c] or $.

This kind of expression gets to be pretty unwieldy and error prone with even a short string. You could write something to generate the expressions for you, but it'd probably be easier to just use a regex implementation that supports negative lookaheads.

*如果您的实现支持非捕获组,那么您可以避免捕获额外的字符。