比如有这样一个字符串: <div><ul id="test1"><li>aaaaa</li><li>bbbbb</li></ul><ul id="test2"><li>cccccc</li><li>ddddd</li></ul></div>我想一次性将id为test1的ul标签里的li标签包含的文本都提取出来。写了如下的表达式:
<ul[^>]*id="test1"[^>]*>(<li>(?:<text>[^<]*)</li>)+[^<]*</ul>,用preg_match来匹配,因为整个表达式我只需要匹配一次就足够了。这个表达式执行完毕后捕获组text里只保存了bbbbb,而没有保存aaaaa。为什么会这样?难道php的捕获组只能保存最后一次捕获的内容?
听说php的正则也不支持平衡组的,我也试过php下的平衡组,是没成功。会不会是因为上面这个原因?平衡组需要能够压栈,可php捕获第二次的时候,就将第一次的数据丢了?要完成上面的匹配,我用php只能分步进行,第一步先匹配出id为test1的ul包含的内容,第二步再用preg_match_all来匹配里面的所有li包含的文本。不知道有没有什么办法用php可以不用分步,一次性匹配出来的?谢谢!
<ul[^>]*id="test1"[^>]*>(<li>(?:<text>[^<]*)</li>)+[^<]*</ul>,用preg_match来匹配,因为整个表达式我只需要匹配一次就足够了。这个表达式执行完毕后捕获组text里只保存了bbbbb,而没有保存aaaaa。为什么会这样?难道php的捕获组只能保存最后一次捕获的内容?
听说php的正则也不支持平衡组的,我也试过php下的平衡组,是没成功。会不会是因为上面这个原因?平衡组需要能够压栈,可php捕获第二次的时候,就将第一次的数据丢了?要完成上面的匹配,我用php只能分步进行,第一步先匹配出id为test1的ul包含的内容,第二步再用preg_match_all来匹配里面的所有li包含的文本。不知道有没有什么办法用php可以不用分步,一次性匹配出来的?谢谢!
用<li>.*</li>的话,一者是贪婪匹配,会匹配出aaaaa</li><li>bbbbb。另外我想要的是aaaaa和bbbbb,希望返回的结果中match数组的test(捕获组名)元素也为一个数组,包含aaaaa和bbbbb两个值。之所以test组会成功捕获两次,是因为我的表达式里用了 (<li>(?:<text>[^<]*)</li>)+,是这个+在起作用。
我现在返回的match结果是:
Array
(
[0] => <ul id="test1"><li>aaaaa</li><li>bbbbb</li></ul>
[1] => <li>bbbbb</li>
[text] => bbbbb
[2] => bbbbb
)
看看这个帖子
http://topic.csdn.net/u/20111123/13/90853673-e439-44bc-8f2e-f75873903951.html
不过我用这种方法来尝试却仍然出现问题:
$reg = '~(?:<ul id="test1">|\G)\K<li>(?<text>\w+)</li>~';
$str = '<div><ul id="test1"><li>aaaaa</li><li>bbbbb</li></ul><ul id="test2"><li>cccccc</li><li>ddddd</li></ul></div>';
preg_match($reg,$str,$match);
print_r($match);
打印的结果是:
Array
(
[0] => <li>aaaaa</li>
[text] => aaaaa
[1] => aaaaa
)
居然只匹配了第一个li。
这是怎么回事?
原来重新寻找搜索头需要在preg_match_all模式下才有效。