正则表达式重写修复

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-zA-Z(case-insensitive 已经匹配)。因此,只有当可以将 faqtagged 请求为除全部小写以外的任何其他内容时,这才会成为问题。

但是,此规则过于通用,因为它允许以任何顺序省略任何后续路径段,包括斜线(路径分隔符)*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”正则表达式也匹配 faqtagged。)

这也可以避免与带有或不带有 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)

(只有第一组正在捕获。)