从正则表达式重定向中排除目录

ric*_*ard 19 regex nginx

我希望将带有下划线的所有URL重定向到它们的虚线等效项.

/nederland/amsterdam/car_rental变成了/nederland/amsterdam/car-rental.为此我使用了这里描述的技术:如何用Nginx替换下划线.所以我的位置块匹配到:

location ~ (_) 
Run Code Online (Sandbox Code Playgroud)

但我只是想这样做对的URL 不是/admin命名空间.为了实现这一点,我尝试将正则表达式与否定查找相结合:正则表达式匹配不包含单词的行?.该位置现在匹配:

(?=^(?!\/admin))(?=([^_]*))
Run Code Online (Sandbox Code Playgroud)

Rubular报告字符串/nederland/amsterdam/car_rental以匹配正则表达式,/admin/stats_dashboard而不匹配,就像我想要的那样.但是,当我将此规则应用于nginx配置时,该站点最终会出现重定向循环.有什么我忽略的吗?

更新:我实际上并不想重写/admin命名空间中的任何内容.下划线到破折号重写应仅在不在/admin命名空间中的所有URL 上进行.

Day*_*ayo 10

Nginx的位置匹配顺序是这样的,使用正则表达式定义的位置在它们的配置文件中出现的顺序被检查并且在第一匹配所述搜索的正则表达式的终止.

有了这些知识,我将简单地使用正则表达式为"admin"定义一个位置,用于您从链接到的Stack Overflow Answer获得的下划线.

location ~ (\badmin\b) {
    # Config to process urls containing "admin"
}
location ~ (_) {
    # Config to process urls containing "_"
}
Run Code Online (Sandbox Code Playgroud)

其中的任何请求admin都将由第一个位置块处理,无论它是否具有下划线,因为匹配的位置块出现在下划线之前.

**PS**

作为我在矿山展示后几天发布的另一个答案,我发布的位置匹配顺序文档的链接也表明您也可以使用^~修饰符来匹配/admin文件夹并跳过下划线的位置块.

我个人倾向于不使用这个修饰符,而是喜欢将带有正则表达式的位置和带注释的注释绑定在一起,但它肯定是一个选项.

但是,根据您的设置,您需要小心,因为以"/ admin"开头但更长的请求可能与修饰符匹配并导致意外结果.

如上所述,我更喜欢我的基于正则表达式的方法是安全的,因为在没有清楚理解的情况下,没有人会开始任意改变配置文件中的事物顺序.

  • 我同意这比尝试只使用一个表达式更好. (2认同)

vks*_*vks 6

^(?!\/admin\b).*
Run Code Online (Sandbox Code Playgroud)

你只需要这个简单的正则表达式.lookahead参见演示.

https://regex101.com/r/uF4oY4/16

您正则表达式会失败/nederland/amsterdam/car_rental,因为它有太多_.所以只有字符串/nederland/amsterdam/car将被考虑.

要么

您可以使用

rewrite ^(?!\/admin\b)([^_]*)_(.*)$ $1-$2;
Run Code Online (Sandbox Code Playgroud)


cns*_*nst 6

你没有明确地提到过这种或那种方式,但看起来你可能只有一个/admin命名空间,它形成了前缀,$uri并且与^/admin.*$正则表达式相匹配; 让我根据这样的假设提供两个非冲突的配置选项.


正如其他人所建议的那样,您可能希望使用单独的locationfor /admin.

但是,与其他答案不同,我建议您通过前缀字符串定义它,并使用^~修饰符在成功匹配后不检查正则表达式.

location ^~ /admin {
}
Run Code Online (Sandbox Code Playgroud)

或者,或者甚至额外的安心和傻瓜式方法,而不是使用链接答案中看似非POSIX正则表达式(如果我认为我在OpenBSD上读取re_format(7)),考虑到你已经知道它^/admin.*是你想要的路径,考虑一些更简单的东西,保证被大多数人声称他们知道RE是什么,并在任何地方工作,更不用说可能更有效率.排除:

location ~ ^/[^a][^d][^m][^i][^n].*_.* {
}
Run Code Online (Sandbox Code Playgroud)

为了实现您的目标,您可以使用这两种解决方案中的任何一种,或者甚至两者都更加严格和万无一失.