我需要一个正则表达式,它只选择那些不以特定扩展名(如 .png 或 .css)结尾的 URL 字符串。
我测试了以下内容:
1)这个使用负面的lookbehind:
(?<!\.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>