Мне нужно сопоставить все теги (например,% 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); ?>
Благодаря! 🙂
То, что вы пытаетесь сделать, – это восстановление промежуточных захватов из групп, которые соответствуют более одного раза для каждого регулярного выражения. Насколько я знаю, только .NET и Perl 6 предоставляют эту возможность. Вам нужно будет выполнить эту работу в два этапа: сопоставить значение атрибута с одним или несколькими %tag%
последовательностей в нем, а затем разбить отдельные последовательности.
Кажется, вам не нравится какой XML-тег или атрибут, с которыми связаны значения, поэтому вы можете использовать это несколько упрощенное выражение для поиска значений с помощью %tag%
последовательностей в них:
'#"([^"%<>]*+%[^%"]++%[^"]*+)"|\'([^\'%<>]*+%[^%\']++%[^\']*+)\'#'
EDIT: это регулярное выражение фиксирует значение атрибута в группе 1 или группе 2, в зависимости от того, какие кавычки он использовал. Вот еще одна версия, которая объединяет альтернативы, поэтому она всегда может сохранить значение в группе 2:
'#(["\'])((?:(?![%<>]|\1).)*+%(?:(?!%|\1).)++%(?:(?!\1).)*+)\1#'
Это:
(%[a-zA-Z0-9]+%)
недостаточно? В вашем примере теги не отображаются нигде вне значений атрибутов – не так ли?
% \ w +% было бы еще более простым способом сделать это.