在单行Perl中查看正则表达式

时间:2019-04-21 23:33:09

标签: perl regex-negation regex-lookarounds

我正在尝试制作一种单行脚本,当githubgolang之后不是时打印。

例如,java is a language used in github应该匹配,但是golang is a language used in github不匹配。

我已经尝试过表达式/(?<!golang).*github/,但是它不起作用。

echo "golang is a language used in github" |
    perl -nle'print /(?<!golang).*github/ ? "match" : "no match"'

这将打印match而不是no match

如何在Perl中使用“负向后看”来做到这一点?

(使用Perl v5.28.1)

3 个答案:

答案 0 :(得分:3)

您的表达式匹配其中所有带有单词“ github”的字符串。让我们看看原因:

/(?<!golang).*github/
只要Perl可以调整.*以匹配足够的字符,而不会碰到紧接golang的情况,

就会匹配。正则表达式很贪婪,.*将尽可能匹配,而其余模式仍匹配。

所以,如果您的字符串是

golang is a language used in github

可以通过将字符串分配给不同部分来匹配正则表达式:

  • (?<!golang)匹配字符串的开头
  • .*获得“ golang is a language used in
  • github获得“ github

完成您想要的目标的一种可能代价高昂的方法是:

/^(?:(?!golang).)*github/

通过确保“ github”之前的所有字符都不以序列“ golang”开头来工作。

所以

echo "java is a language used in github" | perl -ne 'print q!Not golang: !, /^(?:(?!golang).)*github/ ? q!true! : q!false!'

将会在{p> 1期间打印出Not golang: true

echo "golang is a language used in github" | perl -ne 'print q!Not golang: !, /^(?:(?!golang).)*github/ ? q!true! : q!false!'

将打印出Not golang: false


另一种(较少混淆的)方法是进行两个连续的测试:

/^(.*)github/  and  $1 !~ /golang/

如果您要处理成千上万的线,也许可以同时测试两种方法以找出更快的线?

答案 1 :(得分:0)

只需使用否定的前瞻锚定即可开始

^(?!.*golang).*github

答案 2 :(得分:0)

改善波西米亚风格,

/^(?!.*golang.*github).*github/