【问题标题】:Regex multiple URLs with optional parameters, some required for backreference, some not带有可选参数的正则表达式多个 URL,一些需要反向引用,一些不需要
【发布时间】:2015-07-30 14:21:39
【问题描述】:

我有一组我正在执行 301 重定向的 URL(使用 Nginx,我认为它使用 PCRE 作为其正则表达式引擎)。这是所需内容的简化版本:

  • /old/
    • 重定向到/new/
  • /old/1234/
    • 重定向到/new/1234/
  • /old/1234/foo/
    • 重定向到/new/1234/foo/
  • /old/1234/bar/
    • 重定向到/new/1234/bar/
  • /old/1234/expired/
    • 重定向到/new/1234/

即对此的过度简化可能是说/old/(.*) 重定向到/new/$1,除非url 的最后一部分是/[0-9]+/expired/,在这种情况下它只会上升一个级别。 (除非我真的需要使用与 URL 匹配的 foobarexpired1234 部分保持更具体)。

如果可能,我想在一个正则表达式中涵盖所有这些,而不是为每个变体设置多个规则。

所以到目前为止我在Nginx.conf 中的正则表达式类似于:

location ~* ^/old/(([0-9]+/)expired/)?|([0-9]+/(foo|bar/)?)?$ {
    return 301 /new/$1;
}

显然这是不对的。总结:

  • 如果 url 以 /expired/ 结尾,我只想获取 /[0-9]+/ 部分。
  • 以及整个 /[0-9]+/foo//[0-9]+/bar/ 部分,如果它以 foo 或 bar 结尾。
  • 只有 /[0-9]+/ 部分,如果这就是它的结尾。
  • 如果它只是以/old/ 结尾,那么只需重定向到/new/

【问题讨论】:

    标签: regex nginx


    【解决方案1】:

    只要斜线没问题,下面的正则表达式就应该适用于 PCRE。

     ^/old/([0-9]+/.*?)?(?:expired/)?$
    
    • ^/old/ -> 匹配从开始到 /old 的所有内容
    • ([0-9]+/.*?)? -> 可选地匹配数字/和 LAZILY 之后的任何文本。显然,匹配的不仅仅是 foo 和 bar。
    • (?:expired/)?$ -> 可选匹配已过期,与上一步中的惰性匹配,引擎将继续逐个检查字符,然后如果已过期并且下一个字符串结尾,则将从捕获组中删除过期。

    使用 /new/$1 的结果:

    /new/
    /new/1234/
    /new/1234/foo/
    /new/1234/bar/
    /new/1234/
    

    【讨论】:

    • 这看起来可行,谢谢!我刚刚在测试它,我可能会尝试将.*?更改为(foo|bar)?,看看是否可以使其更具体。
    • 是的,这行得通,我必须像 `^/old/([0-9]+/(foo/|bar/)?)?(?:expired/)?$ `
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2017-10-02
    相关资源
    最近更新 更多