我正在尝试使用mod_rewrite将URL从旧主机重定向到使用不同URL格式的新URL。新主机将ID填充为六位数,如下所示:
旧网址:
http://www.example.com/script.cgi?page_id=123
需要重定向到:
http://archive.example.com/000123/
这是我到目前为止所做的:
RewriteCond %{QUERY_STRING} ^page_id=([0-9]+)$
RewriteRule ^script\.cgi http://archive.example.com/%1/? [R=301,L]
这是重定向到:
http://archive.example.com/123/
有没有办法用mod_rewrite实现零填充,或者我只需编写一个处理程序脚本来重定向到正确的URL?
答案 0 :(得分:2)
不是一个优雅的解决方案,但您可以设置六个不同的规则:
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{1})$
RewriteRule ^script\.cgi http://archive.example.com/00000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{2})$
RewriteRule ^script\.cgi http://archive.example.com/0000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{3})$
RewriteRule ^script\.cgi http://archive.example.com/000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{4})$
RewriteRule ^script\.cgi http://archive.example.com/00%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{5})$
RewriteRule ^script\.cgi http://archive.example.com/0%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]+)$
RewriteRule ^script\.cgi http://archive.example.com/%1/? [R=301,L]
答案 1 :(得分:2)
以下是两个更优雅的解决方案:
使用N flag一次添加一个零,直到我们有六位数字:
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)page_id=([0-9]{1,5})(&.*)?$
RewriteRule ^script\.cgi$ $0?page_id=0%3 [N]
RewriteCond %{QUERY_STRING} ^([^&]*&)*page_id=([0-9]{6})(&.*)?$
RewriteRule ^script\.cgi$ http://archive.example.com/%2/? [R=301,L]
使用额外的RewriteCond
预先添加五个零,然后只获取最后六位数字:
RewriteCond %{QUERY_STRING} ^(([^&]*&)*)page_id=([0-9]+)(&.*)?$
RewriteCond 00000%3 [0-9]{6}$
RewriteRule ^script\.cgi$ http://archive.example.com/%0/? [R=301,L]
QUERY_STRING
上应用的复杂模式只是考虑其他网址参数。我更喜欢第二种解决方案,因为它只是一条规则而且更全面。
答案 2 :(得分:1)
另一个选择是使用RewriteMap并让脚本生成要重定向到的URL。
RewriteMap zeropad prg:/usr/local/zeropad.pl
RewriteCond %{QUERY_STRING} ^page_id=([0-9]+)$
RewriteRule ^script\.cgi ${zeropad:%1} [R=301,L]
/usr/local/zeropad.pl是一个包含
之类的可执行脚本#!/usr/bin/perl
$| = 1; #We don't want buffering
while (<STDIN>) {
printf("http://archive.example.com/%06d/?\n",$_);
}
您可以使用您喜欢的任何可执行文件而不是Perl文件。我们的想法是将其打印出来(使用尾随换行符)要重定向到的URL。它必须在读取STDIN的循环中工作,因为Apache将启动脚本一次并重复调用同一个实例。它无法缓冲其输出,因为Apache将在完成重写之前等待其输出(直到换行)。
答案 3 :(得分:0)
好的,我意识到我可以通过以下方式实现我想要的结果:
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{1})$
RewriteRule ^script\.cgi http://archive.example.com/00000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{2})$
RewriteRule ^script\.cgi http://archive.example.com/0000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{3})$
RewriteRule ^script\.cgi http://archive.example.com/0000%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{4})$
RewriteRule ^script\.cgi http://archive.example.com/00%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{5})$
RewriteRule ^script\.cgi http://archive.example.com/0%1/? [R=301,L]
RewriteCond %{QUERY_STRING} ^page_id=([0-9]{6})$
RewriteRule ^script\.cgi http://archive.example.com/%1/? [R=301,L]
有没有其他方法可以在没有多条规则的情况下执行此操作?