用于在行范围内替换的 perl 习语(类似 sed)

perl idiom for substituting in a line range (sed-like)

sed 的一个不错的功能是命令(其中包括替换)可以限制在由正则表达式定义的行范围内(或行号,但不要介意)。这是一个简单的例子:

sed '/^Page 5:/,/^Page 6:/s/this/that/g'  

我只是想将一个相当复杂的 sed 脚本转换为 perl,虽然正则表达式替换没有问题,但我意识到我不知道将替换限制在一定范围内的直接方法。我会写

perl -p -e 's/^(Page 5:.*)this/that/g'

将以 Page 5: 开头的行的 this 更改为 that,但不在后面的行中更改(甚至在这一行中,尽管 g 是因为比赛是不重叠的,所以只会替换一次)。除了编写一个显式输入循环并在 $inrange 之类的状态变量中保持跟踪之外,难道没有一个很好的快捷方式可以做到这一点吗?这个是perl,肯定有!

有。你在 perl 中拥有的是 'range operator'

有点像这样:

if ( m/Page 5:/ .. m/Page 6:/ ) { 
     s/this/that/g;
}

如果您处于两种模式之间,这将评估为 'true',否则为 false。

例如:

use strict;
use warnings;


while (<DATA>) {
    if ( m/Page 5:/ .. m/Page 6:/ ) {
        s/this/that/g;
    }
    print;
}

__DATA__

Page 1:
this
this
more this
Page 5:
this 
this this
this
Page 6:
this 
more this
and some more this