Apache RewriteCond 匹配 www 和非 www
Apache RewriteCond match both www and non-www
我正在尝试根据域名将对 sitemap.xml
的请求重定向到不同的站点地图文件,例如 mydomain.sitemap.xml
或 anotherdomain.sitemap.xml
等...
到目前为止我有这个,但它只适用于非 www 域:
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]
有什么建议吗?
RewriteCond %{HTTP_HOST} (www\.)?([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%2.sitemap.xml [L,NC]
将其更改为您想要的效果:
RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]
更新
为了解释正则表达式,这里是它的作用:
^(?:www\.)?([^.]+)\.
^
表示匹配字符串的开头,因此这会将正则表达式锚定到字符串的开头。
(?:)
表示仅将其用于分组,不捕获匹配的内容(因此在这种情况下不会用完 %1
)。
www\.
只是表示匹配 "www.",点必须用斜杠转义,否则它有特殊含义。
括号后的问号(?:www\.)?
表示该组是可选的,存在或不存在,都匹配成功。
所以此时我们要么仍在字符串的开头,要么就在 "www.".
之后
现在我们继续使用 ([^.]+)\.
将所有内容带到下一个点。这是有效的,因为...
()
是一个捕获组,因此在本例中它捕获与 %1
.
匹配的内容
[^.]+
表示用 [^.]
匹配任何不是点的东西,在这种情况下,点不需要转义,因为它在 "character class" 中。开头的插入符号 ^
使其成为否定匹配,因此匹配未指定的任何内容。之后的 +
表示匹配其中的一个或多个,然后执行 "greedily" 以便它可以匹配最长的字符串。
因此,由于我们是贪婪匹配,这意味着关闭 \.
实际上不是必需的,因为无论如何贪婪匹配都会到达那里,但我喜欢将锚点放在正则表达式中,因为它使它们更容易阅读和理解。这不会造成任何伤害,因为任何有效的主机名在我们匹配的主机名之后都会有另一部分。
另一种选择是使用 (?:\.|$)
来选择字符串末尾的点 或 管道是 "alternation" 说 "this or that" (或者那个,或者那个,如果使用更多的话)。非捕获组用于包含交替。所以在那种情况下它会变成:
^(?:www\.)?([^.]+)(?:\.|$)
这意味着它也适用于 "localhost".
我正在尝试根据域名将对 sitemap.xml
的请求重定向到不同的站点地图文件,例如 mydomain.sitemap.xml
或 anotherdomain.sitemap.xml
等...
到目前为止我有这个,但它只适用于非 www 域:
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]
有什么建议吗?
RewriteCond %{HTTP_HOST} (www\.)?([^.]+) [NC]
RewriteRule ^sitemap\.xml$ /%2.sitemap.xml [L,NC]
将其更改为您想要的效果:
RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.
RewriteRule ^sitemap\.xml$ /%1.sitemap.xml [L,NC]
更新
为了解释正则表达式,这里是它的作用:
^(?:www\.)?([^.]+)\.
^
表示匹配字符串的开头,因此这会将正则表达式锚定到字符串的开头。
(?:)
表示仅将其用于分组,不捕获匹配的内容(因此在这种情况下不会用完 %1
)。
www\.
只是表示匹配 "www.",点必须用斜杠转义,否则它有特殊含义。
括号后的问号(?:www\.)?
表示该组是可选的,存在或不存在,都匹配成功。
所以此时我们要么仍在字符串的开头,要么就在 "www.".
之后现在我们继续使用 ([^.]+)\.
将所有内容带到下一个点。这是有效的,因为...
()
是一个捕获组,因此在本例中它捕获与 %1
.
[^.]+
表示用 [^.]
匹配任何不是点的东西,在这种情况下,点不需要转义,因为它在 "character class" 中。开头的插入符号 ^
使其成为否定匹配,因此匹配未指定的任何内容。之后的 +
表示匹配其中的一个或多个,然后执行 "greedily" 以便它可以匹配最长的字符串。
因此,由于我们是贪婪匹配,这意味着关闭 \.
实际上不是必需的,因为无论如何贪婪匹配都会到达那里,但我喜欢将锚点放在正则表达式中,因为它使它们更容易阅读和理解。这不会造成任何伤害,因为任何有效的主机名在我们匹配的主机名之后都会有另一部分。
另一种选择是使用 (?:\.|$)
来选择字符串末尾的点 或 管道是 "alternation" 说 "this or that" (或者那个,或者那个,如果使用更多的话)。非捕获组用于包含交替。所以在那种情况下它会变成:
^(?:www\.)?([^.]+)(?:\.|$)
这意味着它也适用于 "localhost".