我有一个字符串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.
答案 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+)//;