2012-07-27 72 views

回答

21

您必须在写着边框\b

/\bsprintf\b/ 
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的匹配的起始列。

$.@-特殊变量在perlvar中描述。有关正则表达式的一些很好的阅读可以在perlrequickperlretut中找到。第一个正则表达式非常简单;它只是使用零宽度断言来确保不合格子字符串在其每一侧都有一个字边界。第二个正则表达式使用相同的技术,但也适用于/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

+3

我有兴趣以“这个答案没有用”的方式听到,以便我可以改进它或证明删除它。 – DavidO 2012-07-27 08:49:13

+1

+1为您的非常好的解释。我想你可能已经被低估了,因为这个问题没有说*找到所有不包含snprint_private *的行上的sprintf,所以这可能被认为有点矫枉过正。 – simbabque 2012-07-27 12:30:34

+1

@ - array的使用很好 – gaussblurinc 2012-07-27 13:21:45

相关问题