如何用单条语句对多行字符串仅在分组匹配时执行替换?
用Perl单语句为类YAML字段值添加引号
需求
给类YAML格式文本中,**值包含冒号(:)或值为单个短横线(-)**的字段值添加单引号,其他值保持原样。
尝试过的错误代码
$data =~ s/^(\s*\S+): (.+)$/$1: '$2'/mg if $2 =~ /:/ || $2 =~ /^\-$/;
注:这段代码无效是因为
if条件中的$2在匹配执行前未被捕获,无法正确判断。
输入示例
data: normal: text timestamp: Wed Aug 23 07:07:07 2023 time-zone: UTC +03:00, Daylight Saving: +0h type: - duration: 45h 8m 41s
期望输出
data: normal: text timestamp: 'Wed Aug 23 07:07:07 2023' time-zone: 'UTC +03:00, Daylight Saving: +0h' type: '-' duration: 45h 8m 41s
已有可行多行代码
my @lines = split "\n", $data; foreach my $i (0 .. $#lines) { my $line = $lines[$i]; if ($line =~ /^(\s*\S+): (.+)$/) { my $key = $1; my $val = $2; $lines[$i] = "$key: '$val'" if $val =~ /:/ || $val =~ /^\-$/; # quote invalids } } $data = join "\n", @lines; say $data;
单语句解决方案
将判断条件整合进正则表达式,直接匹配需要处理的行并完成替换:
$data =~ s/^(\s*\S+): ((.*:.*)|^-$)/$1: '$2'/mg;
代码说明
^(\s*\S+)::捕获每行开头的缩进、键名和冒号部分((.*:.*)|^-$):匹配两种需要加引号的值——包含冒号的内容,或单个短横线$1: '$2':将匹配到的行替换为「键名: '值'」的格式/mg:多行匹配修饰符,确保每行独立处理
内容的提问来源于stack exchange,提问作者h q
相关产品推荐
相关产品推荐

