我在nginx中为特定文件启用了缓存,如下所示:
location ~* \.(?:css|js)$ {
access_log off;
add_header Cache-Control "no-transform,public,max-age=31536000,s-max-age=31536000";
expires 1y;
}
我想在这里做的是排除所有匹配模式i18n - *。js的文件,结果缓存除了以i18n开头的所有.js文件。
我尝试进行否定查询以排除模式,但由于非捕获组,它不能作为例外工作:
location ~* \.(?!i18n-.*\.js)(?:css|js)$ {
access_log off;
add_header Cache-Control "no-transform,public,max-age=31536000,s-max-age=31536000";
expires 1y;
}
这里的智能解决方案是什么?我不是正则表达式专家,所以简短的解释也会有所帮助。
答案 0 :(得分:4)
官方文档describes如何遍历位置树:
按照它们出现的顺序检查Rregular表达式 配置文件。正则表达式的搜索终止 在第一次匹配时,使用相应的配置。如果不 匹配正则表达式然后找到配置 使用前面记住的前缀位置。
基于此,配置如下:
location ~* \.(i18n-.*\.js)$ {
access_log off;
expires off;
}
location ~* \.(css|js)$ {
access_log off;
expires 1y;
add_header Cache-Control public;
}
注意:除非用作变量docs:
,否则正则表达式中的问号是多余的以后可以将命名的正则表达式捕获用作变量:
server {
server_name ~^(www\.)?(?<domain>.+)$;
location / {
root /sites/$domain;
}
}
如果使用?:
语法跳过捕获组,则需要稍后使用,否则可以删除以简化位置语法。
答案 1 :(得分:1)
我确信Anatoly的答案是您问题的完整解决方案。我只想提供比评论允许更多的见解。
你的正则表达很好。一个非常好的问题,你的表达非常接近。
这就是为什么它不起作用
. # matches any character except newline
(?!i18n-.*\.js) # A negative lookahead which actually does what you intended it to do
(?:css|js)$` # extension list
.
恰好与此处的文字句点匹配。没有锚或断言,允许从此开始。 (demo)。没有量词,所有尝试都会产生不正确的结果。a(?=1)
会将a
与a1
匹配,但不会与a2
匹配。a(?=1)c
将失败a1c
。a(?=1)1c
或a(?=1)\dc
或a(?=1).c
等将a1c
与a1c
匹配。.*
)或参考点字符(例如^
),这就是在那种情况下发生的事情。添加这样可以使你的表达工作。
值得注意的是,完全为了将来参考,如果你想使用像\/
那样的参考点字符,你会使用像\/
这样的表达式,否则就会包含斜杠的路径可能会产生意想不到的结果。
你拥有所有元素,但正如你所说\/(?!i18n-[^\/]*\.js)[^\/]*(?:css|js)$
。