如何使用Perl中的正则表达式提取URL的一部分?

时间:2015-03-07 21:47:45

标签: perl url

网址的一般格式是 scheme://domain:port/path?query_string#fragment_id

虽然域(以及URL的其他可能部分)可能包含Unicode字符,但在下文中我们假设仅使用ASCII字符。此外,我们假设

  
      
  • scheme仅包含字母a–zA–Z;
  •   
  • domain不包含:?#/;
  •   
  • port是自然数,:port是可选的;
  •   
  • path不包含?#path是可选的;
  •   
  • query_string不包含#?query_string是可选的;
  •   
  • fragment_id可以包含任意字符,#fragment_id是可选的。
  •   

这是我的代码:

@urls = (
    "http://www.example.com/",
    "http://www80.local.com:80/",
    "https://www.ex221.ac.uk:442/perl/rulez?all+q#all.time");

foreach (@urls) {
    print "URL: $_\n";
    ($scheme,$domain,$port,$path,$query,$fragment) = (/(.)(.)(.)(.)(.)(.)/);
    print "SCHEME: $scheme, DOMAIN: $domain, PORT: $port\n";
    print "PATH: $path\n"; print "QUERY: $query\n";
    print "FRAGMENT: $fragment\n\n";
}

如何更改上面代码中的正则表达式,以便正确分隔URL的五个组件,并使用示例URL测试它是否按预期工作。

2 个答案:

答案 0 :(得分:6)

我建议您使用URI module

use URI;

my @urls = (
    "http://www.example.com/",
    "http://www80.local.com:80/",
    "https://www.ex221.ac.uk:442/perl/rulez?all+q#all.time");

foreach (@urls) {
    my $uri = URI->new($_);
    print "URL: $_\n";
    print "SCHEME: ", $uri->scheme, "\n";
    print "DOMAIN: ", $uri->host, "\n";
    print "PORT: ", $uri->port, "\n";
    print "PATH: ", $uri->path, "\n";
    print "QUERY: ", $uri->query, "\n";
    print "FRAGMENT: ", $uri->fragment, "\n";
}

答案 1 :(得分:1)

正则表达式记录在perlre(参考手册)和perlretut(教程)中。

尽管如此,以下是完成作业所需的全部信息。

要匹配任意数量的字符,您可以使用字符类。

[abcdef]      # Matches a, b, c, d, e or f

您可以使用字母范围。

[a-zA-Z]      # Matches any lowercase or uppercase letter

要匹配除某些字符以外的任何字符,请使用^启动课程。

[^abcdef]     # Matches any character except a, b, c, d, e or f

如果您使用*进行操作,则表示零件或更多内容。

ab*c          # Matches ac, abc, abbc, abbbc, ...

如果您不想要特殊的意思,请不要忘记使用\转义特殊字符。

ab\*c         # Matches ab*c