2012-07-27 71 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

相關問題