如何用纯Perl实现匹配指定行后修改下一行内容?
纯Perl实现匹配指定行后修改下一行内容
需求:匹配文本中opts@FieldTitle = "mcape"行,修改其下一行的opts@MainTitle内容,已通过@scrptlines = <$NCLSCRPT>将文件读入数组,现有替换尝试无效,以下是正确实现方案:
正确实现方式
方式一:使用状态标记遍历数组
通过标记变量记录是否需要修改下一行,遍历数组时依次处理:
my $modify_next = 0; foreach my $line (@scrptlines) { # 若标记为需要修改,处理当前行的MainTitle if ($modify_next) { if ($line =~ s/^opts\@MainTitle =.*/opts\@MainTitle = ""MCIN: NODA~C~Valid:"" + dystr(it) + ""\/"" + mnstr(it) + ""\/"" + yrstr(it) + ""Issued:"" + dystr(0) + ""\/"" + mnstr(0) + ""\/"" + yrstr(0)/) { $modify_next = 0; # 修改完成后重置标记 } } # 匹配到目标FieldTitle行,设置修改标记 if ($line =~ /opts\@FieldTitle = ""mcape""/) { $modify_next = 1; } # 保留原有其他替换操作 $line =~ s/DATADir =.*/DATADir = ""$INPUT_DIR[$kk]/""/g; }
方式二:多行正则匹配(将数组转为字符串处理)
把数组拼接成单个字符串,利用多行正则一次性完成匹配替换:
my $content = join('', @scrptlines); # 匹配mcape行及其下一行的MainTitle,替换为目标内容 $content =~ s/(opts\@FieldTitle = ""mcape""\n)opts\@MainTitle =.*/$1opts\@MainTitle = ""MCIN: NODA~C~Valid:"" + dystr(it) + ""\/"" + mnstr(it) + ""\/"" + yrstr(it) + ""Issued:"" + dystr(0) + ""\/"" + mnstr(0) + ""\/"" + yrstr(0)/s; # 若需要恢复数组格式,拆分回数组 @scrptlines = split /(?<=\n)/, $content;
原尝试无效原因说明
- 第一种尝试:遍历单行时,匹配到
opts@FieldTitle = "mcape"的行并非opts@MainTitle行,next unless条件永远不成立,替换逻辑无法触发。 - 第二种尝试:误用sed的语法(
n命令),Perl不支持这种标量上下文的sed风格命令块写法。
内容的提问来源于stack exchange,提问作者Zilore Mumba
相关产品推荐
相关产品推荐

