7

我有一个字符串foo_bar_not_needed_string_part_123。现在在这个字符串中,我只想not_needed_string_partfoo_后面跟着bar.

我使用了以下正则表达式:

my $str = "foo_bar_not_needed_string_part_123";

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

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

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

foo_bar__123.
4

7 回答 7

6

还有另一种方法,而且很简单:

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

诀窍是使用后向检查锚点,并替换此锚点后面的所有非数字符号(不是符号)。基本上,使用这种模式,您只匹配需要删除的符号,因此不需要捕获组。

作为旁注,在原始的正则表达式中(?=bar)bar构造是多余的。第一部分(前瞻)只有在某个位置后面跟着“条”时才会匹配——但这正是模式的非前瞻部分检查的内容。

于 2012-09-16T08:57:32.393 回答
5

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

my $str = "foo_bar_not_needed_string_part_123";
$str =~ s/(foo_bar_).*?(_\d+)/$1$2/;
print $str;
于 2012-09-16T08:59:07.867 回答
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所以如果有直接替换匹配部分的方法,我很感兴趣。我所做的是捕获所需的所有内容,然后用它替换整个字符串。

于 2012-09-16T08:52:33.987 回答
1

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

$str =~ s/(foo_(?=bar)bar_)(.*?)(_\d+)/$1$3/;
于 2012-09-16T08:56:52.563 回答
1

试试这个:

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

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

在您的正则表达式中,它包括结果:

foo_

然后在“foo_”之后寻找“bar”:

(?=bar)

但它不包括在这一步。它包含在下一步中:

bar_

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

所以,一般来说:它在结果中包含您输入的所有内容,除了 (?=bar),它只是在表达式之后寻找“bar”。

于 2012-09-16T09:06:30.207 回答
1

一起去

echo "foo_bar_not_needed_string_part_123" | perl -pe 's/(?<=foo_bar_)[^\d]+//'
于 2012-09-16T11:54:22.970 回答
1

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

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

并且可以将后视替换为\K(keep) 以使其更整洁

$str =~ s/foo_bar_\K.*?(?=_\d+)//;
于 2012-09-16T20:08:01.733 回答