案例一如下:
1 $regex='/[sS]*/'; 2 $str='lemon'; 3 $matches=array(); 4 5 if(preg_match($regex,$str,$matches)){ 6 var_dump($matches); 7 } 8 9 echo "<br/>"; 10 11 $regex='/[sS]*?/'; 12 $str='lemon'; 13 $matches=array(); 14 15 if(preg_match($regex,$str,$matches)){ 16 var_dump($matches); 17 }
第一个正则表达式匹配到lemon
第二个为什么匹配不到?
答案:
第一个中的正则是[s|S]*,表示区配所有字符n次,属于贪婪模式重复区配,即尽可能多的区配字符串。所以会区配$str的所有内容。
第二个正则是[s|S]*?,比第一个多个个文号,?表示重复前面的0次或者一次。由于前面是*,这里*?就表示以勉强模式区配,它是尽可能的以最小的长度区配字符串,
由于*最小的是区配0次,那*?就只能区配0次了。换成+?的话就是区配1次。由于*?区配0次,所以就什么都没有了,是个长度为0的空字符串。
由上面的问题衍生出下面的疑问:
$regex='/[sS]*?abc/'; $str='lemonabc'; $matches=array(); if(preg_match($regex,$str,$matches)){ var_dump($matches); }
为什么这个能匹配的到lemonabc?
答案:
这个是因为你有了截止字符abc,*?第一次开始向右区配直至找到abc开始的时候停止区配,由于你的lemonabc中包含abc,所以是去陪到abc为止,即整个字符串。
如果你的字符串是lemonabcde的话,区配的也是lemonabc,假如你的正则改成[s|S]*?abd的话,那区配的也是个长度为0的空字符串。因为没有找到后面的,那就区配最少的次数0次。