gpt4 book ai didi

正则表达式负后视和前瞻 : equivalence and performance

转载 作者:行者123 更新时间:2023-12-05 00:56:56 26 4
gpt4 key购买 nike

我需要一个正则表达式,它只会选择那些不以 .png 或 .css 等特定扩展名结尾的 URL 字符串。

我测试了以下内容:

1)这个使用负回顾:

(?<!\.png|\.css)$

https://regex101.com/r/tW4fO5/1

2)另一个使用负前瞻:
^(?!.*[.]png|.*[.]css$).*$

https://regex101.com/r/qZ7vA4/1

两者似乎都可以正常工作,但据说 #1(负向后视)在 436 步(见链接)中处理,而 #2(负向后视)据说在 173 步中处理。

所以我的问题是:这是什么意思?会不会影响演出?

最后,这两个正则表达式在功能上真的是等价的吗?

编辑:解决方案摘要

总结一下,考虑到要通过正则表达式排除的字符串结尾的完整列表(一个典型的场景是 Web 服务器设置,其中静态资源由 apache 提供,而动态资源由不同的引擎提供 - 在我的情况下: php-fpm)。

PCRE 正则表达式有两种可能的选择:

1) 负面回顾
$(?<!\.(?:ico|gif|jpg|png|css|rss|xml|htm|pdf|zip|txt|ttf)$|(?:js|gz)$|(?:html|woff)$)
https://regex101.com/r/eU9fI6/1

请注意,我使用了几个 OR ed 后视,因为负后视需要固定宽度的模式(即:您不能混合不同长度的模式)。这使得这个选项的编写稍微复杂一些。此外,在我看来,这降低了它的性能。

2) 负前瞻
^(?!.*[.](?:js|ico|gif|jpg|png|css|rss|xml|htm|html|pdf|zip|gz|txt|ttf|woff)$).*$
https://regex101.com/r/dP7uD9/1

前瞻比后视略快。这是 100 万次迭代的测试结果:

时间回顾 = 18.469825983047 秒
时间前瞻 = 14.316685199738 秒

如果我没有可变长度模式的问题,我会选择后视,因为它看起来更紧凑。反正哪一个都好。最后,我向前看:
<LocationMatch "^(?!.*[.](?:js|ico|gif|jpg|png|css|rss|xml|htm|html|pdf|zip|gz|txt|ttf|woff)$).*$">
SetHandler "proxy:unix:/var/run/php5-fpm.sock|fcgi://www/srv/www/gioplet/web/public/index.php"
</LocationMatch>

最佳答案

Is it going to have an impact on performances?



在大多数情况下,正则表达式需要找到匹配项的步骤越多,性能就越慢。尽管这也取决于您稍后将使用正则表达式的平台(例如,如果您使用 regex101.com 测试在 .NET 中使用的正则表达式,这并不意味着它会导致灾难性的回溯,延迟点匹配正则表达式失败并显示长文本)。

Are the two regex really functionally equivalent?



不,他们不是。 (?<!\.png|\.css)$查找前面没有 .png 的行尾或 .css . ^(?!.*[.]png|.*[.]css$).*$查找不包含 .png 的行或不以 .css 结尾的行.要使它们“等效”(即,如果要确保以 .png.css 结尾的行不匹配),请使用
^(?!.*[.](?:png|css)$).*$
^^^^^^^^^^^^

确保 $png 之后检查和 css在负前瞻中。

正则表达式之间仍然存在差异:第一个将匹配行尾,第二个将匹配整行。

有没有办法加快后视解决方案?

请注意,在字符串内的每个位置检查模式 1 中的后视。模式 2 中的前瞻仅在字符串的开头检查一次。这就是为什么 anchor 定前瞻解决方案在一种情况下会更快 - 如果您不能使用 RightToLeft 修饰符,该修饰符仅在少数正则表达式风格(例如 .NET)中可用。

$(?<!\.(?:png|css)$) 后视解决方案比模式 1 更快,因为后视模式在到达字符串/行的末尾后只检查一次。尽管如此,这需要更多的步骤,因为后视的实现比前瞻的成本更高。

要真正找出哪种解决方案最快,您需要在您的环境中设置性能测试。

关于正则表达式负后视和前瞻 : equivalence and performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35476547/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com