正则表达式具有可选参数的多个 URL,一些需要反向引用,一些不需要
Regex multiple URLs with optional parameters, some required for backreference, some not
我有一组 URLs 我正在为它做 301 重定向(使用 Nginx,我认为它使用 PCRE 作为它的 Regex 引擎)。这是要求的简化版本:
/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/
,除非 url 的最后一部分是 /[0-9]+/expired/
,在这种情况下它只是上一个档次。 (除非我真的需要用匹配 URL 的 foo
、bar
、expired
和 1234
部分使其更具体)。
如果可能的话,我想在一个正则表达式中涵盖所有这些,而不是为每个变体设置多个规则。
所以到目前为止,我在 Nginx.conf
中的正则表达式是这样的:
location ~* ^/old/(([0-9]+/)expired/)?|([0-9]+/(foo|bar/)?)?$ {
return 301 /new/;
}
显然这是不对的。总结:
- 如果 url 以
/expired/
结尾,我只想得到 /[0-9]+/
部分。
- 如果以 foo 或 bar 结尾,则整个
/[0-9]+/foo/
或 /[0-9]+/bar/
部分。
- 如果结尾是
/[0-9]+/
部分。
- 如果它只是以
/old/
结尾,那么只需重定向到 /new/
只要斜杠没问题,下面的正则表达式应该可以与 PCRE 一起使用。
^/old/([0-9]+/.*?)?(?:expired/)?$
^/old/
-> 匹配从开始到 /old 的所有内容
([0-9]+/.*?)?
-> 可选择匹配 digits/and LAZILY 之后的任何文本。显然,匹配的不仅仅是 foo 和 bar。
(?:expired/)?$
-> 可选地匹配expired,加上上一步的lazy,引擎会一直一个char一个char地检查,然后如果过期了,接下来是string的结尾,那么expired从捕获组中删除。
使用 /new/$1 的结果:
/new/
/new/1234/
/new/1234/foo/
/new/1234/bar/
/new/1234/
我有一组 URLs 我正在为它做 301 重定向(使用 Nginx,我认为它使用 PCRE 作为它的 Regex 引擎)。这是要求的简化版本:
/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/
,除非 url 的最后一部分是 /[0-9]+/expired/
,在这种情况下它只是上一个档次。 (除非我真的需要用匹配 URL 的 foo
、bar
、expired
和 1234
部分使其更具体)。
如果可能的话,我想在一个正则表达式中涵盖所有这些,而不是为每个变体设置多个规则。
所以到目前为止,我在 Nginx.conf
中的正则表达式是这样的:
location ~* ^/old/(([0-9]+/)expired/)?|([0-9]+/(foo|bar/)?)?$ {
return 301 /new/;
}
显然这是不对的。总结:
- 如果 url 以
/expired/
结尾,我只想得到/[0-9]+/
部分。 - 如果以 foo 或 bar 结尾,则整个
/[0-9]+/foo/
或/[0-9]+/bar/
部分。 - 如果结尾是
/[0-9]+/
部分。 - 如果它只是以
/old/
结尾,那么只需重定向到/new/
只要斜杠没问题,下面的正则表达式应该可以与 PCRE 一起使用。
^/old/([0-9]+/.*?)?(?:expired/)?$
^/old/
-> 匹配从开始到 /old 的所有内容
([0-9]+/.*?)?
-> 可选择匹配 digits/and LAZILY 之后的任何文本。显然,匹配的不仅仅是 foo 和 bar。(?:expired/)?$
-> 可选地匹配expired,加上上一步的lazy,引擎会一直一个char一个char地检查,然后如果过期了,接下来是string的结尾,那么expired从捕获组中删除。
使用 /new/$1 的结果:
/new/
/new/1234/
/new/1234/foo/
/new/1234/bar/
/new/1234/