从正则expression式redirect中排除目录

我希望将所有带下划线的URLredirect到它们的虚线等价物。

/nederland/amsterdam/car_rental成为/nederland/amsterdam/car-rental 。 为此,我使用这里描述的技术: 如何用Nginxreplace下划线 。 所以我的位置块匹配到:

 location ~ (_) 

但是我只想对不在 /admin命名空间中的URL执行此操作。 为了做到这一点,我尝试将正则expression式与负面查找相结合: 正则expression式匹配不包含单词的行? 。 该位置现在匹配:

 (?=^(?!\/admin))(?=([^_]*)) 

Rubular报告string/nederland/amsterdam/car_rental匹配正则expression式,而/admin/stats_dashboard不匹配,就像我想要的那样。 但是,当我将此规则应用于nginxconfiguration时,站点将以redirect循环结束。 有什么我忽略了吗?

更新:我实际上不想重写/admin命名空间中的任何内容。 下划线到短划线的重写只能发生在不在 /admin命名空间中的所有URL。

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

有了这些知识,在你的鞋子里,我将简单地定义一个使用“admin”的正则表达式的位置,上面是你从Stack Overflow Answer链接到的下划线。

 location ~ (\badmin\b) { # Config to process urls containing "admin" } location ~ (_) { # Config to process urls containing "_" } 

任何带有admin请求都将由第一个位置块进行处理,而不管是否有下划线,因为匹配的位置块出现在下划线之前。

** PS **

另外一个解决方案是在我的展会结束后的几天内发布的,我发布的位置匹配订单文档的链接也表明您也可以使用^~修饰符来匹配/admin文件夹,并跳过位置块下划线。

我个人倾向于不使用这个修饰符,而更喜欢将基于正则表达式的位置与注释注释绑定在一起,但这当然是一种选择。

但是,根据您的设置,您需要小心谨慎,因为以“/ admin”开头的请求可能会与修改器匹配,并导致意外的结果。

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

 ^(?!\/admin\b).* 

你只需要这个简单的正则表达式就可以了。

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

你的正则表达式将会失败/nederland/amsterdam/car_rental因为它只有弦/nederland/amsterdam/car将被考虑。

要么

您可以使用

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

你没有明确地提到这种或那种方式,但是看起来你可能只有一个/admin命名空间,它构成了$uri的前缀,并且会匹配^/admin.*$ regex; 让我提供两个基于这种假设的非冲突配置选项。


正如其他人所建议的那样,您可能要为/admin使用一个单独的location

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

 location ^~ /admin { } 

另外,或者,除了使用看起来是非POSIX正则表达式的链接解决方案(如果我在OpenBSD上读取re_format(7)是可信的 ),考虑一些简单得多的东西,保证被大多数声称他们知道RE是什么东西,并且到处工作的人所理解,更不用说提高效率了,因为你已经知道它是^/admin.*你想排除的路径:

 location ~ ^/[^a][^d][^m][^i][^n].*_.* { } 

为了实现你的目标,你可以使用这两种解决方案中的任何一种,或者甚至可以使用这两种解决方案中的任何一种,以更加僵硬和防呆