3

我想sprintf在我的代码中找到这个词。应该使用什么 Perl 正则表达式?有些行包含类似 的文本sprintf_private,我想排除这些行,但只需要sprintf.

4

2 回答 2

21

您必须\b在单词的边界处使用:

/\bsprintf\b/
于 2012-07-27T07:58:30.257 回答
7

如果要查找所有sprintf不包含 的 on 行,sprintf_private可以使用一对正则表达式:

while( my $line = <DATA> ) {
    next if $line =~ m/\bsprintf_private\b/;
    while( $line =~ m/\bsprintf\b/g ) {
        print "[sprintf] found on line $. at column $-[0]\n";
    }
}

这首先拒绝任何包含sprintf_private. 然后扫描不包含该取消资格的行以查找所有出现的sprintf. 无论在哪里找到,都会打印一条消息,标识文件中的行以及sprintf找到匹配项的起始列。

和特殊变量在perlvar$.中描述。在perlrequickperlretut中可以找到一些关于正则表达式的好读物。第一个正则表达式非常简单;它只是使用零宽度断言来确保不合格的子字符串在其每一侧都有一个单词边界。第二个正则表达式使用相同的技术,但也应用修饰符迭代所有出现的,以防每行出现不止一次。@-\b/gsprintf

零宽度断言\b匹配发生 a\w\W\W\w转换的任何地方。由于字符类\w包含所有字母字符(其中“全部”的构成取决于您的unicode_strings标志或/u),加上下划线和数字(即,标识符中允许的任何字符),您可能会发现\b单词边界过于严格。如果您发现“简单”的解决方案过于幼稚,您可以加倍努力,通过使用如下所示的正则表达式来真正缩小应该作为单词边界的范围:

(?<!\p{Alpha})sprintf(?!\p{Alpha})

如果您选择走这条路,解决方案将如下所示:

while( my $line = <DATA> ) {
    next if $line =~ m/(?<!\p{Alpha})sprintf_private(?!\p{Alpha})/;
    while( $line =~ m/(?<!\p{Alpha})sprintf(?!\p{Alpha})/g ) {
        print "[sprintf] found on line $. at column $-[0]\n";
    }
}

这使用零宽度的负向后查找和零宽度的负向后查找断言拒绝匹配,其中紧靠主子字符串左侧或右侧的字符是“Alpha”字符,而不是使用稍微更天真的\b.

于 2012-07-27T08:10:01.120 回答