我可以使用mod_rewrite重定向到带有零填充参数的URL吗?

时间:2009-08-17 07:18:40

标签: .htaccess mod-rewrite redirect query-string

我正在尝试使用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?

4 个答案:

答案 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)

以下是两个更优雅的解决方案:

  1. 使用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]
    
  2. 使用额外的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]
    
  3. 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]

有没有其他方法可以在没有多条规则的情况下执行此操作?