Несколько совпадений в группе регулярных выражений?
Мне нужно сопоставить все "теги" (например,%thisIsATag%), которые встречаются в атрибутах XML. (Примечание: я гарантированно получу действительный XML, поэтому нет необходимости использовать полный обход DOM). Мое регулярное выражение работает, за исключением случаев, когда в одном атрибуте есть два тега, возвращается только последний.
Другими словами, это регулярное выражение должно найти tag1, tag2, ..., tag6. Тем не менее, он пропускает tag2 и tag5.
Вот забавный маленький тестовый комплект для вас (PHP):
<?php
$xml = <<<XML
<data>
<slideshow width="625" height="250">
<screen delay="%tag1%">
<text x="30%" y="50%" animatefromx="800">
<line fontsize="32" fontstyle="bold" text="Screen One!%tag2% %tag3%"/>
</text>
</screen>
<screen delay='%tag4%'>
<text x="30%" y="50%" animatefromx="800">
<line fontsize='32' fontstyle='bold' text='Screen 2!%tag5%%tag6%'/>
</text>
</screen>
<screen>
<text x="30%" y="50%" animatefromx="800">
<line fontsize="32" fontstyle="bold" text="Screen Tres!"/>
</text>
</screen>
<screen>
<text x="30%" y="50%" animatefromx="800">
<line fontsize="32" fontstyle="bold" text="Screen FOURRRR!"/>
</text>
</screen>
</slideshow>
</data>
XML;
$matches = null;
preg_match_all('#<[^>]+("([^%>"]*%([^%>"]+)%[^%>"]*)+"|\'([^%>\']*%([^%>\']+)%[^%>\']*)+\')[^>]*>#i', $xml, $matches);
print_r($matches);
?>
Спасибо!:)
3 ответа
То, что вы пытаетесь сделать, это восстановить промежуточные записи из групп, которые совпадают более одного раза за соответствие регулярному выражению. Насколько я знаю, только.NET и Perl 6 предоставляют такую возможность. Вам придется выполнить работу в два этапа: сопоставить значение атрибута с одним или несколькими %tag%
последовательности в нем, а затем разбить отдельные последовательности.
Кажется, вам не важно, с каким XML-тегом или атрибутом связаны значения, поэтому вы можете использовать это, несколько более простое регулярное выражение, чтобы найти значения с %tag%
последовательности в них:
'#"([^"%<>]*+%[^%"]++%[^"]*+)"|\'([^\'%<>]*+%[^%\']++%[^\']*+)\'#'
РЕДАКТИРОВАТЬ: Это регулярное выражение захватывает значение атрибута в группе 1 или группе 2, в зависимости от того, в каких кавычках он использовал. Вот еще одна версия, которая объединяет альтернативы, поэтому всегда может сохранить значение в группе 2:
'#(["\'])((?:(?![%<>]|\1).)*+%(?:(?!%|\1).)++%(?:(?!\1).)*+)\1#'
Это:
(%[a-zA-Z0-9]+%)
недостаточно? В вашем примере теги не появляются нигде вне значений атрибутов - не так ли?