Шаблон регулярного выражения в порядке, но вывод не завершен - PullRequest
2 голосов
/ 13 февраля 2011

Я пытаюсь использовать этот шаблон регулярных выражений:

$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 Ответ

2 голосов
/ 13 февраля 2011

Вы не можете напрямую, по крайней мере, не в PHP.Повторные группы захвата всегда содержат последнее найденное выражение. Исключением является .NET, где совпадения с регулярным выражением имеют дополнительное свойство , которое позволяет получить доступ к каждому совпадению повторяющейся группы.Кроме того, Perl 6 может делать что-то подобное, но не PHP.

Решение: используйте

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

Теперь вторая группа захвата содержит все теги <span>,С помощью другого регулярного выражения вы можете извлечь все совпадения:

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

Я использую ~ в качестве разделителя регулярных выражений, кстати - использование | вводит в заблуждение IMO.

...