【问题标题】:regex not stop when using dot matches使用点匹配时,正则表达式不会停止
【发布时间】:2016-10-01 09:54:51
【问题描述】:

我想从包含“站点”一词的页面中删除一些脚本

<scritp>
o.com
bla bla bla
</script><p>this is line></p>

<script>
google.com/jquery.js !
</script>

<scritp>
site.com
bla bla bla
</script><p>aa</p>

CONTENT
STYLE
SIDEBAR
...


<scritp>
site.com
aaa bla bla bla
</script><p>a</p>

我正在使用以下正则表达式:

<scritp>.*?site.*?<\/script>

但它包含与匹配项无关的行。

调试链接:https://regex101.com/r/rC0vF8/2

当我找到匹配项时如何停止:&lt;/script&gt;

我想一次性匹配所有&lt;script&gt;site.com&lt;/script&gt;

【问题讨论】:

标签: php html regex dom pattern-matching


【解决方案1】:

改用这个正则表达式:/&lt;scritp&gt;\nsite.*?&lt;\/script&gt;/gsi

您的正则表达式将获取第一个 &lt;script&gt; 然后下一个 site.* 然后最后一个 &lt;/script&gt;

【讨论】:

  • 只有当&lt;script&gt;标签后的第一个词是site时才有效,否则无效。
【解决方案2】:

令人困惑的外观,您的示例和演示中有一些 scritp 和一些 script。是这个意思吗?但是,如果您的输入方便,您可以使用negative lookahead

<script>((?!</script).)*?site(?1)*</script>
  • ((?!&lt;/script).)*? 匹配 lazily 任意数量的任意字符,而 &lt;/script 不在前面
  • 直到site(?1)* reuses 模式在第一个group 直到&lt;/script&gt; 贪婪。

更多解释和demo at regex101

对于此类问题,通常首选parser 解决方案。取决于输入。

【讨论】:

  • 您的代码在 regex101.com 中完美运行,但不幸的是它在 php 中无法运行,它使页面永远加载,您可以在代码生成器中测试它link
  • @user3325376 嗯,它对我有用。试试$str = preg_replace('~&lt;script&gt;((?!&lt;/script).)*?criteo(?1)*&lt;/script&gt;~si', "__REMOVED__", $str);。也许你有 / 作为模式分隔符或在 php.ini 中设置的一些限制太低
  • 这个正则表达式更具可读性,但比我在评论中建议的效率低。一个经过锻炼的贪婪令牌应该是贪婪的,不是吗? :-) 无论如何,我建议展开这些构造。
  • @WiktorStribiżew 为什么不直接展开你的答案呢?恕我直言,在没有任何解释的情况下抛出一个巨大的正则表达式评论并没有真正的帮助。我提出答案是因为我认为这是性能和可读性之间的折衷/不那么难理解。我知道您的正则表达式性能更好。如果您认为您从 rexegg 或其他地方学到了一些对您有益的常见做法的好术语(:我只是凭感觉写的。如果有错误或可以改进,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
相关资源
最近更新 更多