如何在 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
URL 的一般格式是
scheme://domain:port/path?query_string#fragment_id
虽然域(以及 URL 的其他可能部分)可能包含 Unicode 字符,但在下文中我们假设仅使用 ASCII 字符。此外,我们假设
scheme
only consists of lettersa–z
andA–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