正则表达式以匹配不是特定长度范围的起始两个URL段

时间:2013-02-21 03:31:34

标签: php regex parsing url

我在这种形式的URL中使用两个假子目录来表示区域和语言:

/gb/en/tours/lesson-observation

当开头的两个伪子目录分别为2-3和2-5个字符时,此正则表达式匹配。 (旁注:我不确定为什么我必须在这里使用{1,2}而不是{2,3}。)

/^\/.{1,2}[^\/]\/.{1,4}[^\/]\/(.*)/

如果请求的网址 ^/2-3chars/2-5chars/模式不匹配,我该如何获取原始请求的网址,以便我可以重定向到/gb/en$1。 (这是合乎需要的,因为该网站的英国地区和英语版本是默认的,因此如果在请求的URL中找不到区域和语言代码,则应该使用。)

示例:

/page-name
is not matched by the /2-3/2-5 pattern and so should be redirected to:
/gb/en/page-name

/ca/fr/page-name
is matched by the /2-3/2-5 pattern and so should not be redirected

1 个答案:

答案 0 :(得分:0)

要匹配:

/gb/en/tours/lesson-observation

您可以使用:

/[^/]{2,3}/[^/]{2,5}/.*

现在,您需要检测前两个段何时不在这些范围内,因此第一个段高于或低于2-3个字符:

/[^/]?/                   <-- 0 or 1 characters
/[^/]{4,}/                <-- 4 or more characters
/(?:[^/]?|[^/]{4,})/     <-- Combine the above two with an OR (|)

同样,对于第二部分:

/(?:[^/]?|[^/]{5,})/     <-- 0 or 1 characters, or 5 or more characters

将两者放在一起,你有一个正则表达式,用于与我们的第一个正则表达式不匹配的任何内容:

/(?:[^/]?|[^/]{4,})/(?:[^/]?|[^/]{5,})/.*

请注意,在所有这些正则表达式中,我省略了分隔符,但请记住,您不必使用/作为分隔符。您可以使用#~或任何您想要的字符。好处:如果您不使用/作为分隔符,则可以将/保留在最终正则表达式中

#/(?:[^/]?|[^/]{4,})/(?:[^/]?|[^/]{5,})/.*#   <-- # is the delimiter

修改:由于第二个网址段是可选的,我们需要第二个细分受众群:

(?:/(?:[^/]?|[^/]{5,})/)?

将其带回完整的正则表达式,我们得到(使用锚点和分隔符:

#^/(?:[^/]?|[^/]{4,})(?:/(?:[^/]?|[^/]{5,})/)?.*$#