用于在行范围内替换的 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
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