Regex Issue w / Single Line XML

Я создаю документ слов через XML, последний шаг в этом процессе – удаление любых пустых строк. Кажется, у меня есть шаблон, который работает, когда xml является многострочным; однако он генерируется как одна строка, которая разбивает мой preg_replace. Рассмотрим следующий XML:

**<w:p** w:rsidR="009E48E3" w:rsidRPr="008C0DAB" w:rsidRDefault="009E48E3" w:rsidP="004E0AE3"><w:pPr><w:ind w:right="-540"/></w:pPr><w:rw:rsidRPr="008C0DAB">**<w:t>text that should be included</w:t>**</w:r>**</w:p><w:p** w:rsidR="009E48E3" w:rsidRPr="008C0DAB" w:rsidRDefault="009E48E3" w:rsidP="004E0AE3"><w:pPr><w:numPr><w:ilvl w:val="1"/> <w:numId w:val="10"/></w:numPr><w:tabs><w:tab w:val="clear" w:pos="1440"/><w:tab w:val="num" w:pos="1080"/></w:tabs><w:ind w:right="-540" w:hanging="720"/><w:rPr><w:noProof/></w:rPr></w:pPr><w:r><w:rPr><w:noProof/></w:rPr><w:lastRenderedPageBreak/>**<w:t> ; </w:t>**</w:r>**</w:p>**

Вставить звездочку просто, чтобы попытаться помочь читаемости

Пустые строки всегда находятся между тэгами <w:t></w:t> и содержат период или точку с запятой. Поэтому первый <w:p> должен оставаться, пока второй должен быть удален.

Вот мой шаблон: <w:p .*<w:t>[ ]+?(\.|;)[ ]+?<\/w:t>.*?<\/w:p>

Любая помощь ценится, спасибо!

Проблема с вашим шаблоном заключается в том, что первый .* Будет читать до конца XML, а затем, в конце концов, вернуться к предыдущему тегу <w:t> . Оттуда остальная часть шаблона будет успешно соответствовать остальной части XML. Результат – весь XML захвачен!

Проблема с шаблоном Itchy заключается в том, что lookahead (?!.*w:p ) говорит «только если впереди больше тегов <w:p> ». Другими словами, шаблон будет соответствовать только последнему элементу <w:p> (если его нужно удалить, то есть).

Все эти проблемы связаны с использованием .* . Мой девиз из двух частей – старайтесь не использовать его, если это абсолютно необходимо. Тогда, если вы обнаружите, что это абсолютно необходимо использовать, старайтесь не использовать его 🙂

Будет работать следующий шаблон:

<w:p [^<]++(?:(?!<w:t>)<[^<]++)++<w:t> *+[\.;] *+<\/w:t>[^<]*+(?:(?!<\/w:p>)<[^<]++)++<\/w:p>

Заметки:

  1. .* не использовался вообще!
  2. Притяжательные кванторы ++ и *+ самом деле не нужны, но ускорят регулярное выражение.
  3. Последняя часть может быть упрощена до <\/w:t><\/w:r><\/w:p> если элемент всегда заканчивается так.

Для этой строки вы предоставили следующий шаблон:

 <w:p (?!.*w:p ).*?<w:t>[ ]+?(\.|;)[ ]+?<\/w:t>.*?<\/w:p> 

Я тестировал его на Rubular .

Он использует отрицательный результат .