我希望将带有下划线的所有网址重定向到其虚线等效内容。
E.g。 /nederland/amsterdam/car_rental
变为/nederland/amsterdam/car-rental
。为此,我使用了此处描述的技术:How to replace underscore to dash with Nginx。所以我的位置块匹配:
location ~ (_)
但我仅希望在/admin
命名空间中的不上执行此操作。为了实现这一点,我尝试将正则表达式与否定查找结合起来:Regular expression to match a line that doesn't contain a word?。该位置现在与:
(?=^(?!\/admin))(?=([^_]*))
Rubular报告字符串/nederland/amsterdam/car_rental
以匹配正则表达式,而/admin/stats_dashboard
不匹配,就像我想要的那样。但是,当我将此规则应用于nginx配置时,该站点最终会出现重定向循环。有什么我忽略的吗?
更新:我实际上并不想重写/admin
命名空间中的任何内容。只应在/admin
命名空间中不的所有网址上进行下划线到破折号重写。
答案 0 :(得分:10)
Nginx location matching order使得使用正则表达式定义的位置按照它们在配置文件中的出现顺序进行检查,并且正则表达式的搜索在第一次匹配时终止。
有了这些知识,我将简单地使用正则表达式为" admin"定义一个位置。您从您链接到的Stack Overflow Answer获得的下划线上方。
location ~ (\badmin\b) {
# Config to process urls containing "admin"
}
location ~ (_) {
# Config to process urls containing "_"
}
其中包含admin
的任何请求都将由第一个位置块处理,无论它是否有下划线,因为匹配的位置块出现在下划线之前。
正如我在cnst发布的另一个答案后几天,我发布的位置匹配顺序文档的链接也表明您也可以使用^~
修饰符来匹配{{1} }文件夹并跳过下划线的位置块。
我个人倾向于不使用此修饰符,而更喜欢将带有正则表达式的位置与带注释的注释绑定在一起,但它肯定是一种选择。
但是,根据您的设置,您需要小心,因为以" / admin"开头但更长的请求可能与修饰符匹配并导致意外结果。
如上所述,我更倾向于使用基于正则表达式的方法,因为在没有明确理解的情况下,没有人会开始随意更改配置文件中的内容顺序。
答案 1 :(得分:5)
^(?!\/admin\b).*
您只需要使用lookahead
这个简单的正则表达式。请参阅演示。
https://regex101.com/r/uF4oY4/16
您的正则表达式/nederland/amsterdam/car_rental
也会因_
而失败。因此,只会考虑字符串/nederland/amsterdam/car
。
或
你可以使用
rewrite ^(?!\/admin\b)([^_]*)_(.*)$ $1-$2;