Perl如何将正则捕获组内容存入哈希?URL解析代码返回空哈希求助
Perl正则捕获组存入哈希问题排查与修复
核心问题原因
你的代码存在三个直接导致哈希为空的错误:
- 你使用了正则命名捕获组
(?<name>pattern)语法,但捕获结果默认存储在Perl内置哈希%+中,你声明的$scheme/$domain等变量没有被赋值,始终为undef,因此不会被存入哈希 - 正则匹配后没有判断匹配是否成功,部分URL(如
file:///开头的本地路径)不符合你当前正则的必填规则,会匹配失败 - 部分可选捕获组的量词规则不合理,导致无对应内容时匹配失败
修复方案
1. 捕获组取值逻辑调整
直接从内置哈希%+中读取匹配到的命名捕获内容,无需额外声明变量存储。
2. 正则规则优化
调整可选组的匹配规则,兼容无端口、无路径、无查询参数、无锚点,以及file协议无域名的场景。
3. 匹配结果判断
仅在正则匹配成功后返回解析结果。
修复后完整代码
#!/usr/bin/env perl use strict; use utf8; use warnings; use feature qw(say); use Data::Dumper; sub parse_url { my ($url) = @_; my %hash; # 优化后正则,兼容各类场景 if ($url =~ m!^(?<scheme>[^:]+):/{2,3}(?:(?<domain>[^:/]+)(?::(?<port>\d+))?)?(?<path>/[^?#]*)?(?:\?(?<query_string>[^#]+))?(?:#(?<anchor>.+))?$!) { # 遍历所有捕获到的键值对存入哈希 for my $key (keys %+) { $hash{$key} = $+{$key} if defined $+{$key}; } } return %hash; } while (my $row = <>) { chomp $row; say $row; my %hash = parse_url($row); print Dumper \%hash; }
运行效果说明
修复后的代码可以完全匹配你给出的所有URL示例,输出结果与你的预期一致,其中file:///home/user/.profile会正确识别scheme为file,path为/home/user/.profile,不会额外插入空的domain字段。
内容的提问来源于stack exchange,提问作者alex2020
相关产品推荐
相关产品推荐

