【发布时间】:2017-11-16 17:56:52
【问题描述】:
由于组使用相同的父标签,我在捕获多个组时遇到了一些麻烦。
数据块看起来像这样(为了便于阅读,我已经拆分了行,实际数据没有换行符)
<w:p w:rsidR="100"><w:r><w:p w:rsidR="250"><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r></w:p>
<w:p w:rsidR="500"><w:r><w:p><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r></w:p>
<w:p w:rsidR="150"><w:r><w:p w:rsidR="51"><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r></w:p>
<w:p><w:r><w:p w:rsidR="2"><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r></w:p>
<w:p w:hi="150"><w:r><w:p w:hi="5"><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r></w:p>
由于子标签以相同的根结束标签结尾(由于惰性先行 - 这是我们想要的,因为数据块不止一个),原始正则表达式死亡:
/(<w:p .*?>|<w:p>)(.*?)<\/w:p>/
所以它永远不会捕获超出的数据:“Text Group 2...”。
括号的使用将不起作用,因为子标签也是动态的,即(<w:p .*?>|<w:p>)
负前瞻组应该在这里解决问题,但我一定有什么混淆?这不会产生有效的结果。
/(<w:p .*?>|<w:p>)(.*?(?!(<w:p .*?>|<w:p>).*?<\/w:p>))<\/w:p>/
使用非捕获组确实将惰性量化器带到最后,但它没有(显然)捕获第一部分:
(<w:p .*?>|<w:p>)((?:((<w:p .*?>|<w:p>).*?<\/w:p>)).*?)<\/w:p>
第二个捕获组所需的输出包含以下所有内容:
<w:r><w:p w:rsidR="250"><w:r><w:t>Phrase 1</w:t></w:r></w:p></w:r><w:r><w:t>Phrase 2</w:t></w:r>
注意这与RegEx match open tags except XHTML self-contained tags 不同,标签在这里被识别并且是一个常数。
【问题讨论】:
-
你真的应该用 XML Parser 来解析它,它们就是为做这些事情而设计的。
-
@AlexK。那是我的第一次尝试,它在我的实验中无法正常工作。在正则表达式中绝对可行。
-
你的意思是像regex101.com/r/CLy6SY/1这样的吗?
-
这可能很接近...永远不要跟随它。