1

您能否建议一个正则表达式来重写以下网址:

http://intranet/myApp/index.cfm/go:welcome.home/fruit:orange/car:ford/age:37/music:rock

对此:

http://intranet/myApp/index.cfm?go=welcome.home&fruit=orange&car=ford&age=37&music=rock

它需要能够满足任意数量的不同定义的 url 参数。

目前,我只能设法匹配/替换第一个 url 参数。

    <rule>
        <from>/index\.cfm/go:([^:/]*){1}</from>
        <to>/index.cfm?go=$1</to>
    </rule>

不确定是否可以在它们存在的地方添加“:”到“=”和“/”到“&”的后续替换。

谢谢

4

2 回答 2

1

如果您不能在插值之外的“to”中包含代码,则不能。不过,您可以生成一大堆规则。

my $MAX_ARGS = 20;
my ($p, $q);
for (1..$MAX_ARGS) {
    $p .= sprintf('/([^:/]+){%d}:([^/]*){%d}', $_+0, $_+1);
    $q .= sprintf('&$%d=$%d',                  $_+0, $_+1);
    $q =~ s/^&/?/;
    print <<"__EOI__";
    <rule>
        <from>/index\.cfm$p</from>
        <to>/index.cfm?$q</to>
    </rule>
__EOI__
}
于 2013-01-05T00:37:41.227 回答
1

与解析 HTML 一样,操作 URI 最好使用库来处理许多极端情况和格式复杂性。在这种情况下,使用非常常见的URI 库将 URI 分开并重新组合在一起。

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More;

use URI;

sub path_to_query_string {
    my $uri  = shift;
    my $file = shift;

    # Turn it into a URI object if it isn't already.
    $uri = URI->new($uri) unless eval { $uri->isa("URI"); };

    # Get the path all split up.
    my @path_pairs = $uri->path_segments;

    # Strip everything up to what is the real filename.
    my @path;
    while(@path_pairs) {
        push @path, shift @path_pairs;
        last if $path[-1] eq $file;
    }

    # Put the path bits back.
    $uri->path_segments(@path);

    # Split each key/value pair
    my @pairs;
    for my $pair (@path_pairs) {
        push @pairs, split /:/, $pair;
    }

    # Put them back on the URI
    $uri->query_form(\@pairs);

    return $uri;
}

my %test_urls = (
    "http://intranet/myApp/index.cfm/go:welcome.home/fruit:orange/car:ford/age:37/music:rock" =>
      "http://intranet/myApp/index.cfm?go=welcome.home&fruit=orange&car=ford&age=37&music=rock"
);

for my $have (keys %test_urls) {
    my $want = $test_urls{$have};
    is path_to_query_string($have, "index.cfm"), $want, "path_to_query_string($have)";
}

done_testing;
于 2013-01-05T01:41:24.543 回答