Я создаю документ слов через 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>
Заметки:
.*
не использовался вообще! ++
и *+
самом деле не нужны, но ускорят регулярное выражение. <\/w:t><\/w:r><\/w:p>
если элемент всегда заканчивается так. Для этой строки вы предоставили следующий шаблон:
<w:p (?!.*w:p ).*?<w:t>[ ]+?(\.|;)[ ]+?<\/w:t>.*?<\/w:p>
Я тестировал его на Rubular .
Он использует отрицательный результат .