在START&之间替换文字END字符串,不包括perl中的END字符串

时间:2014-05-22 10:37:45

标签: regex perl

我正在浏览网页上有关使用perl查找和替换两个字符串(例如START和END)之间的文本的示例和问题。我用提供的解决方案成功地做到了这一点。在这种情况下,我的START和END也包含替换文本。我使用的语法是s/START(.*?)END/replace_text/s来替换START和END之间的多行,但是在第一次出现END时会停止替换。

但我想知道如何在perl中替换START和END之间的文本,不包括END。

在:

START
I am learning patten matching.
I am using perl.
END

后:

Successfully replaced.
END

4 个答案:

答案 0 :(得分:6)

要执行检查,但要避免匹配您可以使用的字符positive look ahead

s/START.*?(?=END)/replace_text/s

答案 1 :(得分:3)

一种解决方案是捕获END并在替换文本中使用它。

s/START(.*?)(END)/replace_text$2/s

答案 2 :(得分:2)

另一个选项是使用范围运算符..忽略每一行输入,直到找到块的结束标记,然后输出替换字符串和结束标记:

#!/usr/bin/perl

use strict;
use warnings;

my $rep_str = 'Successfully replaced.';

while (<>) {
    my $switch = m/^START/ .. /^END/;
    print unless $switch;
    print "$rep_str\n$_" if $switch =~ m/E0$/;
}

很容易让它适应一个字符串数组:

foreach (@strings) {
     my $switch = ...
     ...
}

答案 3 :(得分:1)

要使用外观断言,您需要重新定义输入记录分隔符($/)(请参阅perlvar),或许可以将while文件粘贴到内存中。为避免这种情况,range(“触发器”)运算符非常有用:

while (<>) {
    if (/^START/../^END/) {
        next unless m{^END};
        print "substituted_text\n";
        print;
    }
    else {
        print;
    }
}

上面保留输出中START / END块之前或之后的所有行。