Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 从正则表达式重定向中排除目录_Regex_Nginx - Fatal编程技术网

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

Regex 从正则表达式重定向中排除目录,regex,nginx,Regex,Nginx,我希望将所有带下划线的URL重定向到它们的虚线等价物 例如,/nederland/amsterdam/car_-rent变为/nederland/amsterdam/car-rent。为此,我使用了这里描述的技术:。因此,我的位置块匹配到: location ~ (_) 但是我只想在/admin名称空间中的URL上执行此操作。为了实现这一点,我尝试将正则表达式与负查找相结合:。该位置现在与以下内容匹配: (?=^(?!\/admin))(?=([^_]*)) Rubular报告字符串/ne

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

例如,
/nederland/amsterdam/car_-rent
变为
/nederland/amsterdam/car-rent
。为此,我使用了这里描述的技术:。因此,我的位置块匹配到:

location ~ (_) 
但是我只想在
/admin
名称空间中的URL上执行此操作。为了实现这一点,我尝试将正则表达式与负查找相结合:。该位置现在与以下内容匹配:

(?=^(?!\/admin))(?=([^_]*))
Rubular报告字符串
/nederland/amsterdam/car\u rental
以匹配正则表达式,而
/admin/stats\u dashboard
不匹配,正如我所希望的那样。但是,当我将此规则应用于nginx配置时,该站点将以重定向循环结束。有什么我忽略了的吗

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

^(?!\/admin\b).*
您只需要这个带有
前瞻功能的简单正则表达式即可。请参阅演示

您的正则表达式也会失败,因为它已经失败了,所以只会考虑字符串
/nederland/amsterdam/car\u rental

你可以用

rewrite ^(?!\/admin\b)([^_]*)_(.*)$ $1-$2;
这样,使用正则表达式定义的位置将按照其在配置文件中的出现顺序进行检查,正则表达式的搜索将在第一次匹配时终止

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

location ~ (\badmin\b) {
    # Config to process urls containing "admin"
}
location ~ (_) {
    # Config to process urls containing "_"
}
任何包含
admin
的请求都将由第一个位置块处理,无论它是否有下划线,因为匹配的位置块显示在下划线的位置块之前

**PS** 正如cnst在我发布几天后发布的另一个答案所示,指向我发布的位置匹配顺序文档的链接也表明,您也可以使用
^
修饰符匹配
/admin
文件夹,并跳过下划线的位置块

我个人倾向于不使用这个修饰符,更喜欢将基于正则表达式的位置与注释一起标注,但这肯定是一个选项

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


如前所述,我更喜欢基于regex的方法,因为我知道,没有人会在没有明确理解的情况下开始任意更改配置文件中的顺序。

您没有明确提到这种或那种方式,但看起来您可能只有一个
/admin
名称空间,它构成
$uri
的前缀,并与
^/admin.*$
正则表达式匹配;基于这样的假设,让我提供两个不冲突的配置选项


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

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

location ^~ /admin {
}

另一方面,甚至是为了额外的安心和愚笨的方法,而不是从链接答案中使用似乎是非POSIX正则表达式(如果我的阅读是可信的),那么考虑一些简单得多的东西,保证大多数人都知道他们知道REs是什么,并且在任何地方工作,更不用说可能更高效,因为您已经知道要排除的路径是

^/admin.*

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


为了实现您的目标,您可以使用这两种解决方案中的任何一种,甚至可以同时使用这两种解决方案,使其更加严格和简单。

我同意这是一种比仅使用一种表达式更好的方法。我正要回答这个问题,但您更快。=)字符串前缀匹配(与另一个答案一样)比正则表达式匹配快—问题中没有任何东西表明
/admin
不是
$uri
前缀字符串(这样的想法是在最早的答案中自愿提出的,后来被删除了),因此,这个答案不是最佳答案。此外,当有人决定从现在起几个月或几年后重新安排代码时,不必要地依赖
位置
指令的顺序肯定会导致晦涩难懂的海森堡,忘记了位置指令的顺序确实重要这一细微差别。@Dayo在
/admin
名称空间中,我不想处理任何事情。我想将
/admin
名称空间以外的所有URL上的下划线替换为hypens。通过此设置,对
/admin/test\u下划线的请求似乎仍由“\code>块处理。如果按照给定的方式应用配置,则不应如此。此示例代码效率不高,因为您必须多次通过
$uri
才能去除所有下划线。关于单个
/admin
命名空间,您是对的。虽然您的解决方案看起来不错,但它在路径
/amsterdam/test
上不起作用。显然是因为它以“a”开头。