正则用了好些年,有两个东西总结出来是在web开发中非常有用的,尤其在抓取、代码分析中经常用到。
1..*的贪吃性
我们用/\*.*\*/去和字符串/* first comment */ not comment /* second comment */匹配会失败,因为由于 .* 项目的贪吃性,会匹配成整个字符串,于是就会匹配失败,不过,如果在后面加一个问号数量符,则会停止贪吃性,而变成匹配尽可能少的数目,因此模式 /\*.*?\*/ 就会正确匹配。各种数量符的含义并没有改变,只是优先的匹配数目。不要将问号的此用法和其自己作为数量符的使用混淆。因为有两种用法,有时可以两个一起出现,例如 \d??\d 会优先匹配一个数字,但如别无选择也可以匹配两个以使剩余模式匹配。
如果设定了 PCRE_UNGREEDY 选项(此选项 Perl 中没有)则数量符默认不是贪吃型的,但是在个别模式后加上一个问号可以将其变成贪吃型的。换句话说,这可以反转默认的行为。
后面跟上一个 + 的数量符是“占有性”(possessive)的。它会匹配尽可能多的字符而不管剩余的模式。因此 .*abc 可以匹配 “aabc” 但是 .*+abc 就不会,因为 .*+ 已经匹配了整个字符串。自 PHP 4.3.3 起可以用占有性数量符可以来加快处理过程。
2.()子模式的不捕获
如果将字符串 “the red king” 来和模式 the ((red|white) (king|queen))
进行匹配,捕获的子串为 “red king”,”red” 以及 “king”,并被计为 1,2 和 3。
简单的括号实现两种功能的事实不总是有帮助的。经常有需要一组子模式但不需要捕获的时候。如果左括号后面跟着 “?:”,子模式不做任何捕获,并且在计算任何之后捕获的子模式时也不算在内。例如,如果用字符串 “the white queen” 去和模式 the ((?:red|white) (king|queen)) 匹配,捕获的子串是 “white queen” 和 “queen”,并被计为 1 和 2。
因此,最完美的匹配网页中图片 src 部分的正则表达式处理如下:
$str='<p style="padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 200%;"><img border="0" src="upfiles/2009/07/1246430143_4.jpg" alt=""/></p><p style="padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 200%;"><img border="0" src=\'upfiles/2009/07/1246430143_3.jpg\'alt=""/></p><p style="padding: 0px; margin-top: 0px; margin-bottom: 0px; line-height: 200%;"><img border="0" src="upfiles/2009/07/1246430143_1.jpg" alt=""/><img width="280" height="187" alt="" class="imgloading"
original=http://s.yoututuan.com/team/2011/1206/13231497847660.jpg
src="http://s.yoututuan.com/team/2011/1206/13231497847660.jpg" style="display: block; ">';
$pattern="/<img.*?src=['|\"](.*?(?:\.(?:gif|jpg)))['|\"].*?[\/]?>/i";
preg_match_all($pattern,$str,$match);
print_r($match);
以上代码将输出如下内容:
Array
(
[0] => Array
(
[0] => <img border="0" src="upfiles/2009/07/1246430143_4.jpg" alt=""/>
[1] => <img border="0" src='upfiles/2009/07/1246430143_3.jpg' alt=""/>
[2] => <img border="0" src="upfiles/2009/07/1246430143_1.jpg" alt=""/>
[3] => <img width="280" height="187" alt="" class="imgloading"
original=http://s.yoututuan.com/team/2011/1206/13231497847660.jpg
src="http://s.yoututuan.com/team/2011/1206/13231497847660.jpg" style="display: block; ">
)
[1] => Array
(
[0] => upfiles/2009/07/1246430143_4.jpg
[1] => upfiles/2009/07/1246430143_3.jpg
[2] => upfiles/2009/07/1246430143_1.jpg
[3] => http://s.yoututuan.com/team/2011/1206/13231497847660.jpg
)
)