在使用Perl进行搜索和替换期间,如何添加而不是替换文本?

3 regex perl

我正在尝试使用Perl中的正则表达式进行搜索和替换.

我要搜索的文字是:

<space>Number<space>NumberNumberNumber
Run Code Online (Sandbox Code Playgroud)

我想用以下代替:

<space>Number<space>NumberNumberNumberI
Run Code Online (Sandbox Code Playgroud)

我有以下正则表达式,可用于查找字符串:

\s[0-9]\s[0-9[0-9][0-9] 
Run Code Online (Sandbox Code Playgroud)

但是如何更换字符串呢?基本上我只是想在最后附加一个'I'.

我正在使用:

perl -pi -e "s/\s[0-9]\s[0-9][0-9][0-9]/I/;" testFile 
Run Code Online (Sandbox Code Playgroud)

但这是用我取代整个事物而不是追加它.

Cha*_*ens 9

这是后面的参考.只需用括号括起要捕获的文本部分.第一组括号以1美元计算,第二组以2美元计算,依此类推.

s/(\s[0-9]\s[0-9]{3})/$1I/
Run Code Online (Sandbox Code Playgroud)

使用Perl 5.10,我们获得了命名捕获,所以你可以说

s/(?<bodytext>\s[0-9]\s[0-9]{3})/$+{bodytext}I/
Run Code Online (Sandbox Code Playgroud)

插图中的东西<>这个名字.名称成为%+变量中的键,值是捕获的文本.

另一种解决方案是使用零宽度正面观察

s/(?<=\s[0-9]\s[0-9]{3})/I/
Run Code Online (Sandbox Code Playgroud)

或者它是Perl 5.10的新手,简写 \K

s/\s[0-9]\s[0-9]{3}\K/I/
Run Code Online (Sandbox Code Playgroud)

尝试

perl -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename
Run Code Online (Sandbox Code Playgroud)

如果你使用双引号,那么在Perl看到它之前,shell会对$ 1进行插值.如果你认为应该有问题,那么看看Perl看到的东西可能是个好主意.你可以用B :: Deparse做到这一点:

perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/" filename
Run Code Online (Sandbox Code Playgroud)

这将产生以下输出.

BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/(\s[0-9]\s[0-9][0-9][0-9])/I/;
}
continue {
    print $_;
}
-e syntax OK
Run Code Online (Sandbox Code Playgroud)

从中我们可以看出,这$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
Run Code Online (Sandbox Code Playgroud)

一旦逃脱:

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
Run Code Online (Sandbox Code Playgroud)