我有一个带有捕获组的正则表达式,它与我在更广泛的上下文中想要的内容相匹配。然后我采取捕获组$1
并将其用于我的需要。这很容易。
s///
但是,当我只想用替换的内容而$1
不是整个正则表达式替换时,如何使用捕获组呢?
例如,如果我这样做:
$str =~ s/prefix (something) suffix/42/
prefix
并被suffix
移除。相反,我想something
替换为,42
同时保持原样。prefix
suffix
我有一个带有捕获组的正则表达式,它与我在更广泛的上下文中想要的内容相匹配。然后我采取捕获组$1
并将其用于我的需要。这很容易。
s///
但是,当我只想用替换的内容而$1
不是整个正则表达式替换时,如何使用捕获组呢?
例如,如果我这样做:
$str =~ s/prefix (something) suffix/42/
prefix
并被suffix
移除。相反,我想something
替换为,42
同时保持原样。prefix
suffix
据我了解,您可以使用不消耗字符的前瞻或后视。或者将数据保存在组中,只删除您要查找的内容。例子:
具有前瞻性:
s/your_text(?=ahead_text)//;
分组数据:
s/(your_text)(ahead_text)/$2/;
如果您只需要替换一个捕获,那么使用@LAST_MATCH_START
and @LAST_MATCH_END
(with use English
; see perldoc perlvar
) withsubstr
可能是一个可行的选择:
use English qw(-no_match_vars);
$your_string =~ m/aaa (bbb) ccc/;
substr $your_string, $LAST_MATCH_START[1], $LAST_MATCH_END[1] - $LAST_MATCH_START[1], "new content";
# replaces "bbb" with "new content"
这是一个老问题,但我发现下面更容易替换以 to 开头的>something
行>something_else
。适合更改 fasta 序列的标题
while ($filelines=~ />(.*)\s/g){
unless ($1 =~ /else/i){
$filelines =~ s/($1)/$1\_else/;
}
}
我使用这样的东西:
s/(?<=prefix)(group)(?=suffix)/$1 =~ s|text|rep|gr/e;
例子:
在以下文本中,我想规范化空格,但仅限于::=
:
some text := a b c d e ;
这可以通过以下方式实现:
s/(?<=::=)(.*)/$1 =~ s|\s+| |gr/e
结果:
some text := a b c d e ;
解释:
(?<=::=)
: 匹配的后向断言::=
(.*)
: 之后的一切::=
$1 =~ s|\s+| |gr
:使用捕获的组标准化空白。请注意r
确保不尝试修改$1
只读的修饰符。使用不同的子定界符 ( |
) 来不终止替换表达式。
/e
:将替换文本视为 perl 表达式。
使用环视断言。引用文档:
环顾断言是零宽度模式,它匹配特定模式而不将其包含在
$&
. 正断言在其子模式匹配时匹配,负断言在其子模式失败时匹配。Lookbehind 将文本匹配到当前匹配位置,lookahead 匹配当前匹配位置之后的文本。
如果字符串的开头具有固定长度,则可以这样做:
s/(?<=prefix)(your capture)(?=suffix)/$1/
但是,?<=
它不适用于可变长度模式(从 Perl 5.30 开始,它接受长度小于 255 个字符的可变长度模式,这允许使用|
,但仍然阻止使用*
)。解决方法是使用\K
而不是(?<=)
:
s/.*prefix\K(your capture)(?=suffix)/$1/