在单线程perl中查看正则表达式

问题描述 投票:0回答:3

我正在尝试制作一个单行脚本,当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)

perl regex-negation regex-lookarounds
3个回答
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!'

将打印出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/

如果你正在做数十或数十万行,也许可以测试两种方法来找到更快的行?


0
投票

只需使用负面预测就可以开始:

^(?!.*golang).*github

0
投票

改善波希米亚人,

/^(?!.*golang.*github).*github/
© www.soinside.com 2019 - 2024. All rights reserved.