Perl正则表达式找到一个确切的单词

时间:2012-07-27 07:55:12

标签: regex perl

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

2 个答案:

答案 0 :(得分:21)

您必须在'border:

字样使用\b
/\bsprintf\b/

答案 1 :(得分:6)

如果要在不包含sprintf的行上查找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的匹配的起始列。

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

零宽度断言\w\W匹配发生\W\w\w转换的任何位置。由于字符类unicode_strings包含所有字母字符(构成“all”的内容取决于您的/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";
    }
}

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

\b

这使用零宽度负向后观和零宽度负前瞻断言来拒绝匹配,其中主要子串的左侧或右侧的字符是“Alpha”字符,而不是使用稍微更天真的{{1}}