在使用 Perl 进行搜索和替换期间,如何附加而不是替换文本? [英] How can I append instead of replace text during a search-and-replace with Perl?
问题描述
我正在尝试使用 Perl 中的正则表达式进行搜索和替换.
I am trying to do search-and-replace using a regex in Perl.
我要搜索的文字是:
<space>Number<space>NumberNumberNumber
我想用以下内容替换它:
and I want to replace it with:
<space>Number<space>NumberNumberNumberI
我有以下正则表达式可用于查找字符串:
I have the following regex which works in finding the string:
\s[0-9]\s[0-9[0-9][0-9]
但是我该怎么替换字符串呢?基本上我只想在末尾附加一个I".
But what do I do about replacing the string? Basically I just want to append an 'I' to the end.
我正在使用:
perl -pi -e "s/\s[0-9]\s[0-9][0-9][0-9]/I/;" testFile
但是这是用 I 替换整个内容而不是附加到它.
but this is replacing the whole thing with I rather than appending to it.
推荐答案
这就是反向引用的用途.只需用括号将要捕获的文本部分括起来即可.第一组括号以 $1 提供,第二组以 $2 提供,依此类推.
This is what backreferences are for. Just surround the section of text you want to capture with parentheses. The first set of parentheses are available in $1, the second in $2, and so on.
s/(\s[0-9]\s[0-9]{3})/$1I/
使用 Perl 5.10,我们获得了命名捕获,所以你可以说
With Perl 5.10 we gained named captures, so you can say
s/(?<bodytext>\s[0-9]\s[0-9]{3})/$+{bodytext}I/
<
和 >
之间的东西是名字.名称成为 %+
变量中的键,值是捕获的文本.
The stuff inbetween <
and >
is the name. Names become keys in the %+
variable and the values are the captured text.
另一种解决方案是使用 零宽度正向后视
Another solution is to use a zero-width positive look-behinds
s/(?<=\s[0-9]\s[0-9]{3})/I/
或其,Perl 5.10 的新内容,简写 \K
or its, new to Perl 5.10, shorthand \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:
If you use double quotes the $1 is interpolated by the shell before Perl ever sees it. If you have problems with something you think should work, it may be a good idea to take a look at what Perl is seeing. You can do this with 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
缺失.让我们用单引号再试一次:
From this we can see that $1
is missing. Lets try again with single quotes:
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
这篇关于在使用 Perl 进行搜索和替换期间,如何附加而不是替换文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!