我最近了解到使用(*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
对内。
因此,对于之前的文字,我希望仅匹配text3
,text4
和/<div>.*<div>(.*)<\/div>.*<\/div>/gs
以及text2,而不是因为它内部div嵌套在其他div中。
是否可以使用相同的技术做到这一点?
要查找此文本,我只需使用:
/<div>.*<div>(.*)<\/div>.*<\/div>(*SKIP)(*F)|(\[\w+\])/gs
但是当我使用时:
text4
我仍然只获得{{1}}作为匹配而不是其他文本 - DEMO。
如果没有,还有其他简单的技术可以实现吗?
答案 0 :(得分:1)
只需尝试以下正则表达式即可匹配text1
,text3
,text4
,
(?s)<div>(?:(?!<div>).)*?<\/div>(*SKIP)(*F)|\[\K[^\]]*
使用s
修饰符,上面的正则表达式会匹配不包含字符串<div>
的{{1}}标记块,因此下面的块会匹配。
<div>
模式中的 <div>
[text2]
</div>
使匹配失败。现在(*SKIP)(*F)
符号右侧的模式(在我们的例子中是|
)将与剩余的输入匹配。
答案 1 :(得分:1)
这看起来并不漂亮,但这是我能让它发挥作用的唯一方法。这是工作正则表达式:
~<div>(?:(?!</div>).)*?(\[.*?\])(?:(?!</div>).)*?<div>.*?</div>.*?(\[.*?\]).*?</div>|<div>.*?(\[.*?\]).*?</div>|(\[.*?\])~s
您的文字将在所有匹配的群组中捕获。