You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:54:01