寻求移除后紧跟Y行的X行的正则表达式解决方案
移除紧随Y行的X行:正则表达式与Perl代码修正
我需要一个正则表达式,用来移除紧随其后是Y行的X行。我在foreach循环里写了一段Perl代码处理文件,但没法区分“Y行紧跟X行”和“Y行不紧跟X行”的情况,达不到预期效果。
原尝试代码:
foreach my $file (@files) { say "Processing $file in $dir"; open( my $fh, "<", "$file" ) or die "Can't open < $file: $!"; my $data = {}; my $start = "X:"; my $end = "Y:"; my $contents = do { local $/; <$fh> }; my $count = 1; my $transformed = $contents; while ( $contents =~ /$start(.*?)$end/sg ) { say $1 if $1; my $formatted = $1; $formatted =~ s/\s+//g if $formatted; $data->{$file}->{$formatted} = $count++ if $formatted; $transformed =~ /($start.*?$end)/sg; my $removed = quotemeta($1) if $1; $transformed =~ s/$removed/$end/sg if $removed; } push @results, $data if ($data); path($file)->spew_utf8($transformed); }
需要处理的场景(Y行紧跟X行)
输入文本:
{ X: John Smith, Y: 1234 Main Street }
处理后预期结果:
{ Y: 1234 Main Street }
无需处理的场景(Y行未紧跟X行)
输入文本:
{ X: John Smith, X2: 1234567890, Y: 1234 Main Street }
此场景下X行无需移除,保持原内容不变。
修正后的解决方案
原代码逻辑冗余且未精准匹配“X行紧跟Y行”的场景,可通过多行模式正则直接全局替换,同时简化代码:
基础替换版本
foreach my $file (@files) { say "Processing $file in $dir"; open( my $fh, "<", "$file" ) or die "Can't open < $file: $!"; my $contents = do { local $/; <$fh> }; # 匹配X开头行+换行+Y开头行,移除X行保留Y行 $contents =~ s/^X:.*\n(Y:.*)$/$1/gm; path($file)->spew_utf8($contents); }
正则说明
^:多行模式下匹配行开头(m修饰符生效)X:.*:匹配整行X开头的内容\n:匹配X行后的换行符(Y:.*)$:捕获下一行Y开头的内容,作为替换后保留部分gm:全局匹配(g)+ 多行模式(m),处理所有符合条件的行对
保留数据收集的版本
如果需要保留原代码中收集X行内容的逻辑,可调整为:
foreach my $file (@files) { say "Processing $file in $dir"; open( my $fh, "<", "$file" ) or die "Can't open < $file: $!"; my $data = {}; my $count = 1; my $contents = do { local $/; <$fh> }; # 收集符合条件的X行内容 while ($contents =~ /^X:(.*?)\nY:/gm) { my $formatted = $1; $formatted =~ s/\s+//g; $data->{$file}->{$formatted} = $count++ if $formatted; } # 执行内容替换 $contents =~ s/^X:.*\n(Y:.*)$/$1/gm; push @results, $data if %$data; path($file)->spew_utf8($contents); }
此版本既完成了文件内容的精准修改,又保留了原有的数据收集功能,完美区分需要处理和无需处理的场景。
内容的提问来源于stack exchange,提问作者sqldoug
相关产品推荐
相关产品推荐

