这就是后向引用的作用。只需用括号将要捕获的文本部分括起来即可。第一组括号在$1中,第二组在$2中,以此类推。
s/(\s[0-9]\s[0-9]{3})/$1I/
在Perl 5.10中,我们获得了命名捕获功能,因此您可以这样说:
s/(?<bodytext>\s[0-9]\s[0-9]{3})/$+{bodytext}I/
< p > 尖括号内的内容是名称。名称成为
%+
变量中的键,而值则是捕获的文本。
另一种解决方案是使用零宽度正向后瞻
s/(?<=\s[0-9]\s[0-9]{3})/I/
对于 Perl 5.10 版本新增的缩写 \K
s/\s[0-9]\s[0-9]{3}\K/I/
尝试
perl -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename
如果您使用双引号,$1 在 Perl 看到它之前会被 shell 插值。 如果您遇到某些问题,认为应该可以工作,请检查 Perl 正在处理什么。 您可以使用 B::Deparse 来实现:
perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/" filename
这将产生以下输出。
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/I/;
}
continue {
print $_;
}
-e syntax OK
从这可以看出$1
缺失了。让我们再试一次,这次使用单引号:
perl -MO=Deparse -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/;
}
continue {
print $_;
}
-e syntax OK
一旦转义:
perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/\$1I/" filename
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/;
}
continue {
print $_;
}
-e syntax OK