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

How can I extract parts of a URL using regular expressions in Perl?

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

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

  • scheme only consists of letters a–z and A–Z;
  • domain does not contain :, ?, # or /;
  • port is a natural number, :port is optional;
  • path does not contain ? or #, path is optional;
  • query_string does not contain #, ?query_string is optional;
  • fragment_id can contain arbitrary characters, #fragment_id is optional.

这是我的代码:

@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 的五个组成部分,并使用示例 URLs 测试它是否按预期工作。

我建议您使用 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";
}

正则表达式记录在 perlre (reference manual) and perlretut(教程)中。

也就是说,以下是您完成作业所需的全部信息。

要匹配多个字符中的任何一个,您可以使用字符class。

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

您可以使用字母范围。

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

要匹配除某些字符以外的任何字符,请以 ^ 开始 class。

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

如果您在后面跟随着 *,则表示该内容为零个或多个。

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

如果您不想要特殊字符的特殊含义,请不要忘记使用 \ 对它们进行转义。

ab\*c         # Matches ab*c