SKIP FAIL仅忽略部分比赛

时间:2014-07-28 12:05:02

标签: regex preg-match pcre

我最近了解到使用(*SKIP)(*F)帮助删除不需要的匹配。

例如,以下文字:

<div>
[text1]
 <div>

[text2]
 </div>
[text3]
</div>
[text4]

如果我只想在[]之间找到不在<div></div>之间的/<div>.*<\/div>(*SKIP)(*F)|(\[\w+\])/gs [之间的文字(因此结果应该是只有text4我可以使用以下PCRE:

]

那很好。

问题是 - 是否有可能以某种方式使用此技术仅删除左侧网站上的一些匹配组?

我们假设我要删除查找仅查找<div></div>之间的文本(包含那些字符)<div>..</div>和{{1之间}}在其他text1对内。

因此,对于之前的文字,我希望仅匹配text3text4/<div>.*<div>(.*)<\/div>.*<\/div>/gs 以及text2,而不是因为它内部div嵌套在其他div中。

是否可以使用相同的技术做到这一点?

要查找此文本,我只需使用:

/<div>.*<div>(.*)<\/div>.*<\/div>(*SKIP)(*F)|(\[\w+\])/gs

但是当我使用时:

text4

我仍然只获得{{1}}作为匹配而不是其他文本 - DEMO

如果没有,还有其他简单的技术可以实现吗?

2 个答案:

答案 0 :(得分:1)

只需尝试以下正则表达式即可匹配text1text3text4

(?s)<div>(?:(?!<div>).)*?<\/div>(*SKIP)(*F)|\[\K[^\]]*

DEMO

使用s修饰符,上面的正则表达式会匹配不包含字符串<div>的{​​{1}}标记块,因此下面的块会匹配。

<div>
模式中的

<div> [text2] </div> 使匹配失败。现在(*SKIP)(*F)符号右侧的模式(在我们的例子中是|)将与剩余的输入匹配。

答案 1 :(得分:1)

这看起来并不漂亮,但这是我能让它发挥作用的唯一方法。这是工作正则表达式:

~<div>(?:(?!</div>).)*?(\[.*?\])(?:(?!</div>).)*?<div>.*?</div>.*?(\[.*?\]).*?</div>|<div>.*?(\[.*?\]).*?</div>|(\[.*?\])~s

您的文字将在所有匹配的群组中捕获。

Regex Demo