在使用 Perl 进行搜索和替换期间,如何附加而不是替换文本? [英] How can I append instead of replace text during a search-and-replace with Perl?

查看:54
本文介绍了在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆