正则表达式模式匹配正常,但输出不完整

时间:2011-02-13 05:49:07

标签: php regex preg-match preg-match-all

我正在尝试这种正则表达式模式:

$string = '<div class="className">AlwaysTheSame:</div>Subtitle <br /><span class="anotherClass">entry1</span><span class="anotherClass">entry2</span><span class="anotherClass">entry3</span>';
preg_match_all('|<div class="className">AlwaysTheSame:</div>(.*?)<br />(<span class="anotherClass">(.*?)</span>)*|', $string, $matches);
print_r($matches);
exit;

<span class="anotherClass">entry</span>不能存在或存在多次,模式似乎匹配它在存在时和不存在时都很好,但输出是:

Array
(
    [0] => Array
        (
            [0] => <div class="className">AlwaysTheSame:</div>Subtitle <br /><span class="anotherClass">entry1</span><span class="anotherClass">entry2</span><span class="anotherClass">entry3</span>
        )

    [1] => Array
        (
            [0] => Subtitle 
        )

    [2] => Array
        (
            [0] => <span class="anotherClass">entry3</span>
        )

    [3] => Array
        (
            [0] => entry3
        )

)

Array [0] [0]包含完整的字符串,所以它匹配所有我需要的,但在Array [2]和[3]中我只得到最后<span...

如何在输出数组中获取所有<span...而不仅仅是最后一个?

1 个答案:

答案 0 :(得分:2)

你不能直接,至少不能用PHP。重复捕获组始终包含它们匹配的最后一个表达式。 The exception is .NET where regex matches have an additional property,允许您访问重复组的每个匹配项。此外,Perl 6可以做这样的事情 - 但不是PHP。

解决方案:使用

~<div class="className">AlwaysTheSame:</div>(.*?)<br />((?:<span class="anotherClass">(.*?)</span>)*)~

现在第二个捕获组包含所有 <span>标记。使用另一个正则表达式,您可以提取所有匹配项:

~(?<=<span class="anotherClass">).*?(?=</span>)~

顺便说一句,我正在使用~作为正则表达式分隔符 - 使用|令IMO感到困惑。