我想做的事情看似简单,但我找不到让它发挥作用的方法。
我想匹配一个数字,捕获它,然后匹配字符串中后面的N个字符。天真地,我认为这样的事情会起作用:
$myString = "1abc3cdf\n";
# Capture the number, and use a back-reference in the {} to define how many characters to match
$myString =~ s/(\d+).{\1}//g;
print $myString;
我期望得到
bc
,但它只是返回原始字符串1abc3cdf
,即没有发生替换。
我尝试使用扩展的正则表达式(即
s///ge
),但这没有帮助。有什么建议吗?
(??{...})
内联代码块:
$myString =~ s/(\d+)(??{ ".{$^N}" })//g;
参见 Perl 演示。
这里有一些参考:
这是一个“推迟”的正则子表达式。它的行为方式与如上所述的
代码块完全相同,只是它的返回值不是分配给(?{ code })
,而是被视为模式,如果它是字符串则进行编译(或按原样使用)如果它是一个 qr// 对象),则像插入它而不是此构造一样进行匹配。$^R
在该子模式的匹配过程中,它有自己的一组捕获,这些捕获在子匹配期间有效,但一旦控制返回到主模式,这些捕获就会被丢弃。
这里是关于整个正则表达式的更多信息:
(\d+)
- 捕获与任何一个或多个数字匹配的组#1(??{ ".{$^N}" })
- 表示““推迟的”正则子表达式”的代码块,其返回值为“视为模式,如果是字符串则进行编译”。 “$^N
包含与最近关闭的组(子匹配)匹配的任何内容”(请参阅 perlre 参考资料)。换句话说,如果 (\d+)
捕获 45
,则 (??{ ".{$^N}" })
会变成 .{45}
,从而匹配除换行符之外的任何 45 个字符。另一种方法:
my $out = "";
for ( $myString ) {
/\G \D+ /xgc
and $out .= $&;
my ( $count ) = /\G ( \d+ ) /xagc
or last;
if ( length - pos < $count ) {
warn( "Too few characters remaining" );
last;
}
$out .= substr( $_, pos, $count, "" );
}
$myString = $out;
这具有可验证的优点,这意味着它可以检测输入的无效性
4abc
。