我测试了以下内容:
1)使用负回顾后者的正则表达式:
(?<!\.png|\.css)$
https://regex101.com/r/tW4fO5/1
2) 使用负向先行断言的另一种正则表达式:
^(?!.*[.]png|.*[.]css$).*$
https://regex101.com/r/qZ7vA4/1
两种方法都可以正常工作,但是第一种(负回顾)需要处理436步(请参见链接),而第二种(负预测)只需要处理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>