PHP - Preg匹配反转?

时间:2015-05-13 09:51:23

标签: php regex preg-match

如何在PHP中反转Regex表达式?

这是我的代码:

preg_match("!<div class=\"foo\">.*?</div>!is", $source, $matches);

这是检查Container中所有内容的$ source String,并将其存储在$ matches变量中。

但我想做的是反转表达式,即我想要获取容器内部的所有内容。 我知道有一些叫做负面预测的东西,但我对正则表达式的表现非常糟糕,并且没有设法提出一个有效的解决方案。

只需使用?!

preg_match("?!<div class=\"foo\">.*?</div>!is", $source, $matches);

似乎不起作用。

谢谢!

2 个答案:

答案 0 :(得分:1)

新解决方案

由于您的目标是移除匹配的div,如评论中所述,使用原始正则表达式preg_split,加上implode将是更简单的解决方案:

implode('', preg_split('~<div class="foo">.*?</div>~is', $text))

Demo on ideone

旧解决方案

我不确定这是不是一个好主意,但这是我的解决方案:

~(.*?)(?:<div class="foo">.*?</div>|$)~is

Demo on regex101

可以从每场比赛的捕获组1 中选择结果。

请注意,最后一个匹配始终为空字符串,并且在2个匹配的div之间可以存在空字符串匹配,或者如果字符串以匹配的div开头。但是,无论如何你需要连接它们,所以它似乎不是问题。

这个想法是依赖于懒惰量词.*?将始终在推进自身之前尝试续集(无论之后是什么)这一事实,从而产生类似于前瞻性断言的内容确保.*?匹配的任何内容都不在<div class="foo">.*?</div>内。

div标记在每个匹配中匹配,以使光标前进到结束标记。 $用于匹配最后一个匹配div之后的文本。

s标志使.匹配任何字符,包括行分隔符。

修订:我必须将.+?更改为.*?,因为.+?处理字符串,其中2个匹配的div彼此相邻,字符串以匹配的div开头

无论如何,用正则表达式修改HTML并不是一个好主意。 Use a parser instead

答案 1 :(得分:0)

<div class=\"foo\">.*?</div>\K|.

您只需使用\K即可完成此操作。

  

\ K重置报告的匹配的起点。任何先前消费的字符不再包含在最终匹配中