正则表达式重写修复
Regex rewrite fix
我的 .htaccess 文件中有以下 2 个重写规则:
# Rule 1
RewriteRule ^(AL|AK|AZ|AR|CA|CO)/?([a-zA-Z-]+)?/?(faq|tagged)?/?([a-zA-Z0-9-]+)?$ /pages/seo.select-page.php?state=&location=&page=&title= [NC,L]
# Rule 2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)/?$ /pages/seo..php [L]
总的来说它工作正常,直到我的第二个规则需要指向一个以与规则 1 相同的字母开头的页面。
例如:
mydomain.co/copyright
在这种情况下它默认为:
mydomain.co/CO
我试过添加字符数,但似乎没有用。
(AL|AK|AZ|AR|CA|CO){2}
我该如何解决这个问题?
RewriteRule ^(AL|AK|AZ|AR|CA|CO)/?([a-zA-Z-]+)?/?(faq|tagged)?/?([a-zA-Z0-9-]+)?$ /pages/seo.select-page.php?state=&location=&page=&title= [NC,L]
为了避免与您的示例 URL (example.com/copyright
) 发生冲突,您可以简单地删除第一条规则中的 NC
标志,使其成为 case-sensitive匹配 - 特别是前两个大写字符。第二个和第三个 path-segments(“位置”和“标题”)已经匹配 a-z
和 A-Z
(case-insensitive 已经匹配)。因此,只有当可以将 faq
或 tagged
请求为除全部小写以外的任何其他内容时,这才会成为问题。
但是,此规则过于通用,因为它允许以任何顺序省略任何后续路径段,包括斜线(路径分隔符)*1,这将导致无效的重写(如您的示例所示)。
(*1是可选的分隔符,可以让/copyright
匹配成功。)
要允许第二个、第三个和第四个路径段是可选的,但只能按该顺序并重要地强制执行斜线分隔符,那么您可以调整正则表达式以包含一系列嵌套的 non-capturing 子组:
RewriteRule ^(AL|AK|AZ|AR|CA|CO)(?:/([a-zA-Z-]+)(?:/(faq|tagged)(?:/([a-zA-Z0-9-]+))?)?)?$ /pages/seo.select-page.php?state=&location=&page=&title= [L]
这现在只允许 /state
或 /state/location
或 /state/location/page
或 /state/location/page/title
形式的 URL。 (除了“location”和“title”的正则表达式非常相似 - 所以它们可能会被颠倒。“location”正则表达式也匹配 faq
和 tagged
。)
这也可以避免与带有或不带有 NC
标志的 URL 之类的 /copyright
发生冲突,因为 2 个字符的“状态”代码后的斜线定界符是强制性的,如果“位置”存在。
但是,如所写,此修改后的规则不允许 URL 以尾部斜杠结尾,而您之前的规则允许这样做。
旁白:
I've tried adding char count but it didn't seem to work.
(AL|AK|AZ|AR|CA|CO){2}
这不是“字符数”。 {2}
是一个数字量词,正好匹配前面的模式两次。所以,在这种情况下,它实际上匹配了 4 个大写字符。相当于:
(AL|AK|AZ|AR|CA|CO)(?:AL|AK|AZ|AR|CA|CO)
(只有第一组正在捕获。)
我的 .htaccess 文件中有以下 2 个重写规则:
# Rule 1
RewriteRule ^(AL|AK|AZ|AR|CA|CO)/?([a-zA-Z-]+)?/?(faq|tagged)?/?([a-zA-Z0-9-]+)?$ /pages/seo.select-page.php?state=&location=&page=&title= [NC,L]
# Rule 2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)/?$ /pages/seo..php [L]
总的来说它工作正常,直到我的第二个规则需要指向一个以与规则 1 相同的字母开头的页面。
例如:
mydomain.co/copyright
在这种情况下它默认为:
mydomain.co/CO
我试过添加字符数,但似乎没有用。
(AL|AK|AZ|AR|CA|CO){2}
我该如何解决这个问题?
RewriteRule ^(AL|AK|AZ|AR|CA|CO)/?([a-zA-Z-]+)?/?(faq|tagged)?/?([a-zA-Z0-9-]+)?$ /pages/seo.select-page.php?state=&location=&page=&title= [NC,L]
为了避免与您的示例 URL (example.com/copyright
) 发生冲突,您可以简单地删除第一条规则中的 NC
标志,使其成为 case-sensitive匹配 - 特别是前两个大写字符。第二个和第三个 path-segments(“位置”和“标题”)已经匹配 a-z
和 A-Z
(case-insensitive 已经匹配)。因此,只有当可以将 faq
或 tagged
请求为除全部小写以外的任何其他内容时,这才会成为问题。
但是,此规则过于通用,因为它允许以任何顺序省略任何后续路径段,包括斜线(路径分隔符)*1,这将导致无效的重写(如您的示例所示)。
(*1是可选的分隔符,可以让/copyright
匹配成功。)
要允许第二个、第三个和第四个路径段是可选的,但只能按该顺序并重要地强制执行斜线分隔符,那么您可以调整正则表达式以包含一系列嵌套的 non-capturing 子组:
RewriteRule ^(AL|AK|AZ|AR|CA|CO)(?:/([a-zA-Z-]+)(?:/(faq|tagged)(?:/([a-zA-Z0-9-]+))?)?)?$ /pages/seo.select-page.php?state=&location=&page=&title= [L]
这现在只允许 /state
或 /state/location
或 /state/location/page
或 /state/location/page/title
形式的 URL。 (除了“location”和“title”的正则表达式非常相似 - 所以它们可能会被颠倒。“location”正则表达式也匹配 faq
和 tagged
。)
这也可以避免与带有或不带有 NC
标志的 URL 之类的 /copyright
发生冲突,因为 2 个字符的“状态”代码后的斜线定界符是强制性的,如果“位置”存在。
但是,如所写,此修改后的规则不允许 URL 以尾部斜杠结尾,而您之前的规则允许这样做。
旁白:
I've tried adding char count but it didn't seem to work.
(AL|AK|AZ|AR|CA|CO){2}
这不是“字符数”。 {2}
是一个数字量词,正好匹配前面的模式两次。所以,在这种情况下,它实际上匹配了 4 个大写字符。相当于:
(AL|AK|AZ|AR|CA|CO)(?:AL|AK|AZ|AR|CA|CO)
(只有第一组正在捕获。)