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

问题描述 投票:0回答:2

我想做的事情看似简单,但我找不到让它发挥作用的方法。

我想匹配一个数字,捕获它,然后匹配字符串中后面的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
),但这没有帮助。有什么建议吗?

regex perl
2个回答
6
投票

您可以使用

(??{...})
内联代码块:

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

参见 Perl 演示

这里有一些参考:

这是一个“推迟”的正则子表达式。它的行为方式与如上所述的

(?{ code })
代码块完全相同,只是它的返回值不是分配给
$^R
,而是被视为模式,如果它是字符串则进行编译(或按原样使用)如果它是一个 qr// 对象),则像插入它而不是此构造一样进行匹配。

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

这里是关于整个正则表达式的更多信息:

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

0
投票

另一种方法:

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

© www.soinside.com 2019 - 2024. All rights reserved.