我正在尝试制作一种单行脚本,当github
在golang
之后不是时打印。
例如,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)
答案 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/