如何将YAML中的重复键转换为数组?
将YAML重复键转换为数组的解决方案
你的场景是YAML存在重复键,需要将其自动转为数组,而YAML::XS要么覆盖重复键,要么开启ForbidDuplicateKeys后直接报错,无法满足需求。可以用YAML::PP模块实现这个功能,它支持自定义处理重复键的逻辑。
解决方案代码
use Data::Dumper; use YAML::PP; # 配置YAML解析器,处理重复键为数组 my $yp = YAML::PP->new( duplicate_keys => 'allow', hooks => { on_duplicate_key => sub { my ($yp, $hash, $key, $value) = @_; # 若键已存在,转为数组并追加新值 if (exists $hash->{$key}) { my $existing = $hash->{$key}; $hash->{$key} = [ $existing ] unless ref $existing eq 'ARRAY'; push @{$hash->{$key}}, $value; } else { $hash->{$key} = $value; } return 1; }, }, ); # 你的输入YAML字符串 my $yaml_string = <<'YAML'; info: family: skywalker person: id: 1 status: active details: gender: male name: first: Anakin last: Skywalker children: Leia children: Han Solo person: id: 58 status: active details: gender: female name: first: Padme last: Amidala children: Leia children: Han Solo YAML # 解析并重新生成符合要求的YAML my $data = $yp->load_string($yaml_string); print $yp->dump_string($data);
代码说明
YAML::PP的on_duplicate_key钩子会在遇到重复键时触发,我们在钩子函数里判断:如果键已经存在,就把原有值转为数组(如果还不是数组的话),再将新值追加进去;如果不存在就直接赋值。- 运行这段代码后,输出的YAML会和你期望的格式完全一致,重复的
person和children键都会被转为数组结构。
为什么不用YAML::XS?
YAML::XS的设计逻辑是要么覆盖重复键(默认行为),要么禁止重复键并抛出错误(开启$YAML::XS::ForbidDuplicateKeys = 1),没有提供将重复键转为数组的内置机制,因此无法满足你的需求。
内容的提问来源于stack exchange,提问作者h q
相关产品推荐
相关产品推荐

