htaccess 正则表达式无法正确处理 URL

htaccess 正则表达式无法正确处理 URL

我正在尝试重定向(或“重写”)一个网站的 3000 多个 URL,我们更新了大多数内容页面的 SEF,以删除不需要/不需要的 ID 号。这应该是使用正则表达式的简单过程;然而,我了解到正则表达式和 htaccess 更像是一门“艺术”,而不是科学 :-(

以下是我的规则:

RewriteRule ^topics\/([-0-9a-zA-Z]+)?\/([0-9]+)(-)([0-9a-z,-]+)? http://example.net/topics/$1/$4 [L,R=301]

大多数 URL 是这样的:

http://example.net/topics/management/6309-investing-proceeds-from-sale-of-a-farm-or-ranch

并与正则表达式配合良好;但是,如果文章以数字开头,则 URL 如下:

http://example.net/topics/management/3542-9-new-years-resolutions-for-cattle-producers

然后正则表达式(上面)不仅抓取第一组 4 位 ID 数字,还抓取应该留下的第一个数字(在本例中为“9”),结果如下:

http://example.net/topics/management/new-years-resolutions-for-cattle-producers

这显然是行不通的。

此外,作为一种解决方法,我尝试创建一些自定义规则来处理具有这种格式的几个页面/ URL(文章标题开头带有数字),并在正则表达式规则之前添加一条规则,如下所示:

Redirect 301 /topics/management/3542-9-new-years-resolutions-for-cattle-producers http://example.net/topics/management/9-new-years-resolutions-for-cattle-producers

或者

RewriteRule ^topics\/([-0-9a-zA-Z]+)?\/([0-9]{1,4}?)(-)([0-9,a-z,-]+)? http://example.net/topics/$1/$4 [L,R=301]

但是,当我这样做时,正则表达式规则(在 htaccess 文件中进一步)仍然运行,导致“9”被删除。

我已经在许多不同的正则表达式和 htaccess 测试站点上测试了这一点并且它们都运行正常;然而,它在实时服务器上仍然会失败。

Web 服务器是:Apache/2.2.25 (Unix) mod_hive/4.0 mod_ssl/2.2.25 OpenSSL/1.0.0-fips mod_bwlimited/1.4 mod_fcgid/2.3.6

我已经联系了我的服务器/托管公司,他们说他们没有专业知识来解决这个问题。

有人能看出问题出在哪里吗?我搜索了这里和其他地方的数百个论坛帖子,没有人遇到完全相同的问题。

答案1

我刚刚尝试了您的设置,但对您的配置做了一些小改动。我在配置文件中而不是 .htaccess 中使用它进行配置(请注意,它搜索以 /topics 开头的条目,而不是以 Topics 开头的条目):

RewriteRule ^/topics\/([-0-9a-zA-Z]+)?\/([0-9]+)(-)([0-9a-z,-]+)? http://example.net/topics/$1/$4 [L,R=301]

然后测试就可以按预期进行:

[root@proxy conf]# curl -i http://localhost/topics/management/3542-9-new-years-resolutions-for-cattle-producers
HTTP/1.1 301 Moved Permanently
Date: Wed, 15 Apr 2015 14:48:09 GMT
Server: Apache
Location: http://example.net/topics/management/9-new-years-resolutions-for-cattle-producers
Content-Length: 289
Content-Type: text/html; charset=iso-8859-1

编辑1:

请试试这个:

RewriteRule ^topics\/([-0-9a-zA-Z]+)?\/(\d+)(-)([0-9a-z,-]+)? http://example.net/topics/$1/$4 [L,R=301]

在第一个破折号之前的数字不是用 而是用([0-9]+)代替(\d+),在我的设置中仍然有效,也许在你的设置中这(\d+)会让你的 apache 编译感觉更舒服。

相关内容