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

如何用单条语句对多行字符串仅在分组匹配时执行替换?

用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:57:02