正则表达式捕获使用相同父标签的子组

RegEx to capture sub group that uses the same parent tags

由于这些组使用相同的父标签,我在捕获多个组时遇到了一些麻烦。

数据块看起来像这样(为了便于阅读,我将行分开了,实际数据没有换行符

<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 不同,标签在此处标识并且是常量。

我能够通过使用 分支重置组 ?| 来解决这个问题,它允许我结合子模式 + 通配符,同时使用惰性运算符找到尾巴。

示例:

<w:p[^>]*>((?|(<w:p[^>]*>.*?<\/w:p>)|(.))*?)<\/w:p>