我想在我的代码中查找单词
sprintf
。应该使用哪个 Perl 正则表达式?
有些行包含类似 sprintf_private
的文本,我想将其排除,但只需要sprintf
。你必须在单词边界使用\b
:
/\bsprintf\b/
如果您想查找所有不包含 sprintf_private
的行中 sprintf
的所有出现,可以使用一对正则表达式:
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
。无论在何处找到它,在文件中标识该行和匹配起始列的消息都将被打印出来。
$.
和@-
是在perlvar中描述的特殊变量。关于正则表达式的一些好文章可以在perlrequick和perlretut中找到。第一个正则表达式非常简单;它只使用了\b
零宽度断言来确保限定子字符串两边都有单词边界。第二个正则表达式使用了同样的技术,但还应用了/g
修饰符以迭代处理所有出现的sprintf
,以防万一每行可能会有多个出现。
零宽度断言\b
匹配任何\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";
}
}
\b
。
sprintf
是可以忽略的。无论如何,我想技术上没有任何错误,所以我暂时保持原样。 - DavidOsnprint_private
变成了sprintf_private
,因此我已经更新了答案以反映这一变化。 - DavidOsprintf_private
子句的意思是,虽然“sprintf”很重要,但如果后面跟着“_private”,那么它就不重要了。在这种情况下,“next if ...”第一个检查变得不必要,第二个检查应该以(?!\p{Alpha})
结尾,这样下划线就被视为转换。 - DavidO