未知数量的正则表达式替换,如何?

时间:2015-06-04 20:24:37

标签: regex .htaccess

我需要以下列方式更改大量URI:

  1. %20分隔符替换为短划线-
  2. 用旧域替换旧根。
  3. 示例:

    /old_root/first/second.html -> http://new_domain.com/first/second
    /old_root/first/second%20third.html -> http://new_domain.com/first/second-third
    /old_root/first/second%20third%20fourth.html -> http://new_domain.com/first/second-third-fourth
    

    我使用正则表达式提出的最好的方法是编写尽可能多的模式替换规则,作为我的URI中可能出现的%20个分隔符的最大数量:

    old_root/(.*?)/(.*?)\.html -> http://new_domain.com/$1/$2
    old_root/(.*?)/(.*?)%20(.*?)\.html -> http://new_domain.com/$1/$2-$3
    old_root/(.*?)/(.*?)%20(.*?)%20(.*?)\.html -> http://new_domain.com/$1/$2-$3-$4
    

    我的问题是:是否可以使用单个正则表达式规则获得相同的结果?

    我认为我可以使用两步法:首先将所有%20分隔符更改为-,然后使用规则old_root/(.*?)/(.*?)\.html -> http://new_domain.com/$1/$2/。但是,我需要将此规则作为.htaccess指令应用于RedirectMatch文件中,据我所知,不可能对同一重定向指令使用两个连续的规则。

2 个答案:

答案 0 :(得分:1)

事实证明,Apache递归地应用所有正则表达式规则,直到它们停止匹配。因此,我可以写两条规则而不是一条来解决我的问题。

以下规则可以满足我的需求,甚至更多;我在我的本地Apache服务器上测试了它们,它们工作正常。请注意,要使它们起作用,您需要先通过前置

打开重写引擎
RewriteEngine on
Options +FollowSymlinks -MultiViews

在本地.htaccess文件或全局httpd.conf文件中。

用连字符替换所有空格

用连字符替换文字空格和%20

RewriteRule ^(.+)(\s|%20)(.+)$ /$1-$3 [R=301,NE,L]

用连字符替换所有撇号

用连字符替换所有文字撇号和%60

RewriteRule ^(.+)('|`|%60)(.+)$ /$1-$3 [R=301,NE,L]

删除尾随的.html扩展程序

RewriteRule (.+)\.html$ $1 [R=301,L]

将网址中的最后一个字段转换为小写

将URL中的最后一个字段转换为小写并添加新域:

RewriteRule /whatever/(.*?)/(.*?)/(.*) http://new.domain.com/$1/$2/${lc:$3} [R=301,L]

重要提示: 只有在Apache配置文件httpd.conf末尾包含以下行时,小写转换才有效,该配置文件通常位于服务器上的etc目录:

RewriteEngine on
RewriteMap lc int:tolower

最后一点:我建议在每个规则前加上RewriteCond指令,以限制规则的应用领域。例如,要将空格到连字符规则仅应用于与某个正则表达式匹配的URI,您应该在.htaccess文件中写下以下内容:

RewriteCond %{REQUEST_URI} regex_for_URIs
RewriteRule ^(.+)(\s|%20)(.+)$ /$1-$3 [R=301,NE,L]

其中regex_for_URIs是URI必须匹配的正则表达式,以便应用下一个RewriteRule;它也可以是一个简单的字符串。

答案 1 :(得分:0)

嗯,你差不多完成了。

<强>问题

  • 不要返回"%20" - 我们会将它们用作路径部分的“分隔符”
  • 在第三个和第二个添加条件第四组(因为您可能会传递短URL,即您的示例)

<强>解决方案

\/old_root\/(.*?)\/(\w*)(?:%20)?(\w*)?(?:%20)?(\w*)?\.html

请参阅Demo

<强>解释

  • (?:%20)?表示"%20"是非捕获组,可以发生0或1次。
  • 相同的逻辑适用于可能的第3和第第四部分。