正则表达式匹配子串的缺席

时间:2016-06-01 02:43:36

标签: regex perl

我正在寻找只在某些子字符串不存在时匹配的正则表达式。特别是 - 如果一行代码没有从方法中分配或返回返回值。

示例:

this.execute(); // should match

var x = this.execute(); // no match

return this.execute(); // no match

我试图使用以下正则表达式

^(?!.*=|return).*execute\(\).*

这适用于正则表达式测试人员等 - 但我得到了#per;无效的perl运算符"在实践中使用时的例外情况。

谢谢..

5 个答案:

答案 0 :(得分:2)

由于您只想排除分配或返回它很容易被否定

while (<DATA>) { print if not /(?:=|return)\s+this\.execute/ }

__DATA__
this.execute();
var x = this.execute();
return this.execute();

这仅打印行this.execute();

使用Lookaround Assertions,您提供的否定前瞻可以正常工作

if (/^(?!.*=|return)\s+this\.execute/x) { print "$_\n" }

对于负面的背后隐藏,有一个问题。首先,这是有效的

if ( /(?<! =\s )       this\.execute/x ) { print "$_\n" }
if ( /(?<! return \s ) this\.execute/x ) { print "$_\n" }

这会将= return排除在外,一个空格。问题是,我们不能将\s+置于其中,也不能进行交替 - Perl不能为此特定断言执行此操作,请参阅perlretut。我们得到

Variable length lookbehind not implemented in regex m/(?<!=\s+)this\.execute/ at

我们可以使用\s+在断言之外添加不同的空格this...,然后合并多个条件以提供=和{{1}之间没有空格的可能性}}。

但是,如果您可以使用常规的否定匹配,则没有理由这样做。

报告的错误只能是基本语法。这是关于你运行的确切代码,而不是正则表达式。

答案 1 :(得分:1)

如果我理解这个问题不太确定,但您可能会考虑尝试这个问题。 ^this.execute\(\);

答案 2 :(得分:1)

在这种情况下,最好在匹配中找到“最低公分母”,以区别于相似的字符串。在这种情况下,可以忽略var x - 通过说“方法调用之前的任何内容 - 单独的方法调用不是”来满足您的要求。那个语句可能有点太紧了,所以让我们把它改为“在方法调用正常之前,除了空格以外的其他方法,否则标记调用”。这意味着;

my $method_call = qr/ ( this \. \w+ ) \( /x;
while (<$fh>) {
    if (/ ^ \s* $method_call /x) {
        warn "Found method call on line $.: $1\n"
    }
}

我预设$fh是源代码文件的文件句柄。我还做了一些假设,你可能需要调整一下如何定义一个方法调用 - 即。参数的开放括号是强制性的。使用“扩展模式正则表达式”允许在正则表达式中使用空格以便于阅读。此外,使用“引用规则”允许在另一个内部使用名称引用正则表达式以使事情更清晰。

另一方面,如果您想在确定之前坚持var xreturn的存在,我们可以撤消搜索 - 即显式查找“ok”情况并标记任何其他电话:

my $method_call = qr/ ( this \. \w+ ) \( /x;
while (<$fh>) { 
    next if / ^ \s* return \s+ $method_call /x;         # return OK
    next if / ^ \s* var \s+ \w+ = \s+ $method_call /x;  # var OK

    warn "Found method call on line $.: $1\n" if /$method_call/ ;
}

这些都有点冗长,但更清楚地表明你想要做什么。

答案 3 :(得分:1)

我认为这里没有足够的信息。我这样说是因为以下内容适用于shell

~$ echo "execute()"| perl -ne 'print if /^(?!.*=|return).*execute\(\).*/'
execute()
~$ echo "return execute()"| perl -ne 'print if /^(?!.*=|return).*execute\(\).*/'

~$

在上面的代码中,我在shell中运行一个衬管,将一个字符串传递给perl程序。如果字符串与正则表达式匹配,则perl程序将打印该字符串。我的正则表达式没有错误。

错误可能是由于您的perl版本或其他完全可能发生的错误。

我使用的是perl v5.22.2

答案 4 :(得分:0)

我的意思是,简单的答案是,只需在您的测试中使用!运算符,但如果您想知道以下情况,请进行转换:
/expression/ =&gt; /^(?!.*expression)/(在JavaScript中使用DOTALL或[^]
/^expression/ =&gt; /^(?!expression)/