Php懒惰的正则表达式不会表现得很懒惰

时间:2015-07-27 07:06:03

标签: php regex

我需要移除几个页面中的网址。 它以几种不同的方式实现,如脚本源,在脚本中用作变量,或者在noscript标记中使用img src。

我已经写了以下正则表达式来解决这个问题:

/<[no]*script[\s\S]+?www.badurl.com[\s\S]+?<\/[no]*script>/i

问题是,它不会一直懒惰。

在下面的示例中,它应该只选择最后一个脚本块,但它确实选择了两个:

<script type="text/javascript">
var stuff = {"foo":"bar"}foo.c(stuff,1);
</script>

<script type="text/javascript">
<!--
var foo="http://www.badurl.com/cgi-bin/;[comment]";
document.write("<img src=\""+bar+"?r="+escape(document.referrer)+"&d="+(Math.random()*100000)+"\" width=\"1\" height=\"1\" alt=\"foobar\" />");
//-->
</script>

我的错误在哪里?

1 个答案:

答案 0 :(得分:1)

延迟量词不会向后工作,因为文本是从左到右读取的。这样做的方式是第一个<script是正则表达式开始匹配您的内容的地方,它可以匹配,因为在出​​现任意数量的字符badurl链接后,其余的按照您的想法运行。

你正在处理部分HTML / php解析,所以它不是真的小菜一碟,而且通常不建议你做。重做正则表达式:<(no)?script([\s\S](?!<\/(no)?script))+www.badurl.com[\s\S]*?<\/(no)?script>,如https://regex101.com/r/uE9lZ8/3所示。这应该有用,只要角色后面没有</script>标签就可以匹配每个角色。