在 Perl 中,如何匹配数字 N 和接下来的 N 个字符?

DaG*_*aMs 3 regex perl

我想做的事情看似简单,但我找不到一种方法来使其发挥作用。

我想匹配一个数字,捕获它,然后匹配字符串中后面的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;
Run Code Online (Sandbox Code Playgroud)

我期望得到bc,但它只返回原始字符串1abc3cdf,即没有发生替换。

我尝试使用扩展的正则表达式(即s///ge),但这没有帮助。有什么建议么?

Wik*_*żew 8

您可以使用(??{...})内联代码块:

$myString =~ s/(\d+)(??{ ".{$^N}" })//g;
Run Code Online (Sandbox Code Playgroud)

请参阅Perl 演示

这里有一些参考:

这是一个“推迟的”正则子表达式。它的行为方式与上面描述的代码块完全相同(?{ code }),除了它的返回值,而不是被分配给$^R,被视为一个模式,如果它是一个字符串则编译(或者如果它是一个 qr//对象),然后进行匹配,就像插入它而不是此构造一样。

在该子模式的匹配过程中,它有自己的一组捕获,这些捕获在子匹配期间有效,但一旦控制返回到主模式,这些捕获就会被丢弃。

以下是有关整个正则表达式的更多信息:

  • (\d+)- 捕获与任何一个或多个数字匹配的组#1
  • (??{ ".{$^N}" })- 表示“一个”推迟的“正则子表达式”的代码块,其返回值是“视为模式,如果是字符串则进行编译”。“$^N包含与最近关闭的组(子匹配)匹配的任何内容”(请参阅​​ perlre 参考资料)。换句话说,如果(\d+)捕获45,则 会(??{ ".{$^N}" })变成.{45}并因此匹配除换行符之外的任何 45 个字符。