具有单行XML的正则表达式问题

时间:2013-01-20 13:45:18

标签: php regex

我正在通过XML创建一个word文档,该过程的最后一步是删除任何空白行。我似乎有一个模式,当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:r w: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>

任何帮助都会被提供,谢谢!

2 个答案:

答案 0 :(得分:1)

您的模式存在的问题是,第一个.*会直接读到XML的末尾,然后最终回溯到 last <w:t>标记之前。从那里,模式的其余部分将成功匹配XML的其余部分。结果 - 捕获整个XML!

Itchy模式的问题在于,前瞻(?!.*w:p )只有在前面没有<w:p>个标签时才会显示&#34;&#34;。换句话说,模式只会匹配 last <w:p>元素(如果需要删除它,那就是)。

所有这些问题源于.*的使用。我的两部分座右铭是,除非绝对必要,否则尽量不要使用它。然后,如果您发现 绝对有必要使用它,更加努力不使用它:)

以下模式可行:

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

注意:

    完全没有使用
  1. .*
  2. 占有量词++*+并非真正需要,但会加速正则表达式。
  3. 如果元素总是这样结束,则最后一部分可以简化为<\/w:t><\/w:r><\/w:p>

答案 1 :(得分:0)

对于此字符串,您提供了以下模式:

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

我在Rubular上测试了它。

它使用negative lookahead