Perl:如何只替换匹配的字符串部分?

时间:2012-09-16 08:49:19

标签: regex string perl

我有一个字符串foo_bar_not_needed_string_part_123。现在,在此字符串中,我只想在not_needed_string_part后跟foo_时删除bar

我使用了下面的正则表达式:

my $str = "foo_bar_not_needed_string_part_123";

say $str if $str =~ s/foo_(?=bar)bar_(.*?)_\d+//;

但它删除了整个字符串,只打印了换行符。

所以,我需要的是只删除匹配的(。*?)部分。那么,输出是

foo_bar__123.

7 个答案:

答案 0 :(得分:5)

还有另一种方式,而且非常简单:

my $str = "foo_bar_not_needed_string_part_123";
$str =~ s/(?<=foo_bar_)\D+//gi;
print $str;

诀窍是使用lookbehind check anchor,并替换 anchor (不是符号)后面的所有非数字符号。基本上,使用此模式,您只匹配需要删除的符号,因此无需捕获组。

作为旁注,原始正则表达式(?=bar)bar构造是多余的。第一部分(lookahead)只有在某个位置后跟'bar'时才会匹配 - 但这正是用模式的非超前部分检查的内容。

答案 1 :(得分:4)

您可以捕获您不想删除的部分:

my $str = "foo_bar_not_needed_string_part_123";
$str =~ s/(foo_bar_).*?(_\d+)/$1$2/;
print $str;

答案 2 :(得分:1)

你可以试试这个:

my $str = "foo_bar_not_needed_string_part_123";

say $str if $str =~ s/(foo_(?=bar)bar_).*?(_\d+)/$1$2/;

输出:

  

foo_bar__123

PS:我是perl/regex的新手,所以我感兴趣的是有没有办法直接替换匹配的部分。我所做的就是捕获所需的一切,而不是用它替换整个字符串。

答案 3 :(得分:1)

什么是将字符串分成3部分,只删除中间部分?

$str =~ s/(foo_(?=bar)bar_)(.*?)(_\d+)/$1$3/;

答案 4 :(得分:1)

试试这个:

(?<=foo_bar_).*(?=_\d)

在此变体中,它在.*foo_bar_之间包含结果ALL(_"any digit")。

在你的正则表达式中,它包含在结果中:

foo_

然后它在“foo _”之后查找“bar”:

(?=bar)

但它不包含在此步骤中。它包含在下一步中:

bar_

然后(.*?)_\d+包含其余行。

所以,一般来说:它包括你输入的所有这些,EXCEPT(?= bar),它只是在表达后寻找“bar”。

答案 5 :(得分:1)

跟着

echo "foo_bar_not_needed_string_part_123" | perl -pe 's/(?<=foo_bar_)[^\d]+//'

答案 6 :(得分:1)

在这种情况下,你可以使用look-behind / look-ahead

$str =~ s/(?<=foo_bar_).*?(?=_\d+)//;

并且后视可以替换为\K(保持)以使其更加整洁

$str =~ s/foo_bar_\K.*?(?=_\d+)//;