我正在尝试制作一个单行脚本,当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)
您的表达式匹配所有字符串,其中包含单词“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!'
将打印出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/
如果你正在做数十或数十万行,也许可以测试两种方法来找到更快的行?
只需使用负面预测就可以开始:
^(?!.*golang).*github
改善波希米亚人,
/^(?!.*golang.*github).*github/