Apache RewriteCond匹配www和非www

时间:2017-06-20 16:49:55

标签: apache mod-rewrite web no-www

我正在尝试根据域名将对sitemap.xml的请求重定向到不同的站点地图文件,例如mydomain.sitemap.xmlanotherdomain.sitemap.xml等等。

到目前为止,我有这个,但它只适用于非www域:

RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

RewriteCond %{HTTP_HOST} (www\.)?([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%2.sitemap.xml [L,NC]

答案 1 :(得分:1)

将其更改为此应该可以满足您的需求:

RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]

<强>更新

为了解释正则表达式,这是它的作用:

^(?:www\.)?([^.]+)\.

^表示匹配字符串的开头,因此这会将正则表达式锚定到字符串的开头。

(?:)表示只使用此功能进行分组,不捕获匹配的内容(因此在这种情况下它不会用完%1)。

www\.只是说匹配“www。”,点必须用斜线转义,否则它有特殊含义。

括号(?:www\.)?后面的问号表示该组是可选的,它存在或不存在,两者都是成功的匹配。

所以在这一点上,我们要么仍然在字符串的开头,要么就在“www。”之后。

现在我们继续使用([^.]+)\.将所有内容带到下一个点。这是因为......

()是一个捕获组,因此在这种情况下,它会捕获与%1匹配的内容。

[^.]+表示匹配任何不是[^.]点的内容,在这种情况下,点不需要转义,因为它位于此“字符类”中。开头的插入符^使其成为负匹配,因此未指定的任何内容都匹配。之后的+表示匹配其中的一个或多个,并“贪婪地”执行此操作,以便匹配最长的字符串。

因为我们贪婪地匹配,这意味着关闭\.实际上并不是必需的,因为无论如何贪婪的匹配都会去那里,但我喜欢把锚放在正则表达式中因为它使它们更容易阅读并明白。这不会造成任何伤害,因为任何有效的主机名将在我们匹配的主机名之后有另一部分。

另一种选择是使用(?:\.|$)来选择点 作为字符串的结尾,其中管道是“交替”说“这个或那个“(或那,或者,如果使用更多)。非捕获组用于包含交替。所以在那种情况下它会变成:

^(?:www\.)?([^.]+)(?:\.|$)

这意味着它也适用于像“localhost”这样的东西。