【问题标题】:Apache RewriteCond match both www and non-wwwApache RewriteCond 匹配 www 和非 www
【发布时间】:2017-11-23 08:12:22
【问题描述】:

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

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

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

有什么建议吗?

【问题讨论】:

    标签: apache mod-rewrite web no-www


    【解决方案1】:

    把它改成这个应该做你想做的:

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

    更新

    为了解释正则表达式,它的作用如下:

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

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

    (?:) 表示仅将其用于分组,不要捕获匹配的内容(因此在这种情况下它不会用完 %1)。

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

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

    所以此时我们要么仍在字符串的开头,要么就在“www.”之后。

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

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

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

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

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

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

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

    【讨论】:

    • 嗨@SuperDuperApps,我正在学习正则表达式,你能解释一下吗?
    • 当然,我会在答案中添加解释。
    • @Marco 我添加了一个解释正则表达式的更新。如果你喜欢我的回答,可以在左上角打勾接受。欢迎来到 SO :)
    【解决方案2】:
    RewriteCond %{HTTP_HOST} (www\.)?([^.]+) [NC]
    RewriteRule ^sitemap\.xml$ /%2.sitemap.xml [L,NC]
    

    【讨论】:

    • 查看我的回答,虽然这两种方法都可以,但它对此略有改进。同样的想法。
    猜你喜欢
    • 2014-07-12
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2010-11-09
    • 2018-01-07
    • 2018-07-23
    相关资源
    最近更新 更多