使用以下正则表达式
<w:p.*?\$\{test\}.*?\/w:p>
我试图匹配第一个
<w:p>
在&#34; $ {test}&#34;之前和第一个
</w:p>
后。后工作得很好,使用?量词,但它拒绝在第一个停止
<w:body><w:p w:rsidRDefault="00271ADB"/><w:p w:rsidR="00C15291"><w:pPr><w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p></w:body>
这就是我所期望的结果:
<w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p>
但是这是返回的内容
<w:p w:rsidRDefault="00271ADB"/><w:p w:rsidR="00C15291"><w:pPr><w:p w:rsidR="0093632F" w:rsidRDefault="0093632F"><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr><w:br/><w:t>${test}</w:t></w:r></w:p>
这是编辑器中的结果:http://i.imgur.com/HKSYdY8.png
这是我期待的结果:http://i.imgur.com/8HmThRb.png
答案 0 :(得分:3)
您必须将第一个.*?
更改为具有否定前瞻的重复组。您还应该注意到我在\s
之后添加了<w:p
,因此<w:pPr
无法匹配。如果您有一些<w:p>
个实例,则可能需要将其更改为<w:p(?:\s|>)
。
<w:p\s(?:(?!<w:p\s).)*?\$\{test\}.*?\/w:p>
RegEx从左到右匹配,因此没有真正的方法可以说&#34; lazy before&#34;。而不是.*?
我使用了(?:(?!<w:p\s).)*?
。让我们打破这个:
(?: (?# begin non-capturing group for grouping/repetition)
(?! (?# begin negative lookahead)
<w:p\s (?# no <w:p ahead)
) (?# end negative lookahead)
. (?# match any character)
)*? (?# lazy repetition)
这是如何工作的,一旦我们匹配<w:p\s
,我们就进入非捕获/重复组。它执行零长度断言以确保<w:p\s
在该点之前不存在,然后匹配一个字符。这懒惰地重复,直到我们点击${test}
。如果表达式在前瞻中看到<w:p\s
,它将失败......并且新匹配将开始备份,在开头匹配<w:p\s
(并开始做更多的前瞻)。