从 Perl 正则表达式中提取特定值

Extracting specific values from a Perl regex

我想使用 Perl 正则表达式从文件名中提取某些值。 他们有以下(有效)名称:

testImrrFoo_Bar001_off
testImrrFooBar_bar000_m030
testImrrFooBar_bar231_p030

从上面我想提取前 3 位数字(始终保证为 3),以及字符串的最后一部分,在最后一个 _ 之后(可以是 off ,或(mp)后跟 3 位数字)。所以我要提取的第一件事是 3 位数字,第二个是字符串。

我想出了以下方法(我意识到这可能不是最 optimal/nicest 的方法):

my $marker = '^testImrr[a-zA-z_]+\d{3}_(off|(m|p)\d{3})$';
if ($str =~ m/$marker/)
{
    print "1= 2=";
}

只有 </code> 有一个有效结果(即我想要的最后一位信息),但 <code> 结果是空的。关于如何获得中间那 3 位数字的任何想法?

你快到了。

刚刚:
- 通过在括号中添加括号来捕获三位数:(\d{3})
- 不要通过在括号 ((?:m|p)) 之后添加 ?: 来捕获 m|p,或者使用 [mp] 代替:

^testImrr[a-zA-z_]+(\d{3})_(off|[mp]\d{3})$

你会得到:

1=001 2=off
1=000 2=m030
1=231 2=p030

您可以同时捕获两者,例如使用

if ($str =~ /(\d{3})_(off|(?:m|p)\d{3})$/ ) {
    print "1=, 2=".$/;
}

您的示例也有两个捕获组(off|(m|p)\d{3}m|p)。如果您是第一个文件名,对于第二个捕获组,由于匹配另一个分支,不会捕获任何内容。对于 non-capturing 组使用 (?:yourgroup).

当一个简单的 split and substr 就足够时,真的不需要正则表达式:

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @fields = split(/_/);
    my $digits = substr($fields[1], -3);

    print "1=$digits 2=$fields[2]\n";
}

__DATA__
testImrrFoo_Bar001_off
testImrrFooBar_bar000_m030
testImrrFooBar_bar231_p030

输出:

1=001 2=off
1=000 2=m030
1=231 2=p030