1

我需要在文本文件中查找标识符:

但如果标识符是关键字,我不想要匹配。例如,如果我将“for”作为关键字,则如下所示:

for (i=0 ; i< max ; i++)

我应该得到:

Found: i
Found: i
Found: max
Found: i

我研究了前瞻断言,但我无法使其工作:

$IDENTIFIER="(?!(for|while|do))[a-zA-Z_]+[a-zA-Z0-9_]*"
    while ($entireFile =~ /($IDENTIFIER)/g)
    {
          print "Found ($1)" . "\n"; 
    } 

我得到:

Found: or
Found: i
Found: i
Found: max
Found: i

这不是我想要的安静!我明白为什么我得到“或”,但我怎样才能让它更聪明并完全排除“为”呢?

4

3 回答 3

1

即使在 Perl 中,清晰度也很重要。我建议将单词查找正则表达式从关键字过滤器中分离出来,以使测试更易于阅读、更新等。此外,如果您想过滤掉很多关键字,制作一个单独的列表比将它们塞进一个正则更容易表达。这是一个例子:

use strict;
use warnings;

my $entireFile = "for (i=0 ; i< max ; i++)";
my @KEYWORDS = ('for', 'while', 'do');

while ($entireFile =~ /([a-zA-Z_][a-zA-Z0-9_]*)/g)
{
    my $is_keyword = 0;
    for my $keyword (@KEYWORDS) 
    {
        if ($1 eq $keyword) 
        {
            $is_keyword = 1;
        }
    }
    if (not $is_keyword) 
    {
        print "Found ($1)" . "\n";
    }
}
于 2012-08-17T02:08:04.960 回答
1

您需要锚定以确保匹配整个单词(潜在标识符)。第一个近似值,/\b(?!(?:for|while|do)\b)[A-Za-z_][A-Za-z0-9_]*\b/实际上是你想要的。

于 2012-08-17T02:31:24.760 回答
0

您不能只寻找看起来像标识符的东西,因为您可能正在查看评论。您只会寻找可能出现标识符的标识符。标识符不能紧跟在“f”之后。换句话说,真正的问题是你不是锚定问题。

您没有显示您的问题,因此我们无法帮助您解决问题。我们只能盲目地回答你的问题:

$ID_START = "[a-zA-Z_]";
$ID_CONT  = "[a-zA-Z0-9_]";
$IDENT    = "(?<!$ID_START)(?<!$ID_CONT)(?!(?:for|while|do)(?!$ID_CONT))$ID_START$ID_CONT+";

(这也解决了“完成”与“做”不同的问题。)

于 2012-08-17T01:45:38.773 回答