我想使用Perl正则表达式从文件名中提取某些值。 它们具有以下(有效)名称:
testImrrFoo_Bar001_off
testImrrFooBar_bar000_m030
testImrrFooBar_bar231_p030
从上面我想提取前三个数字(总是保证为3),以及字符串的最后一部分,在最后一个_
之后(可以是off
,或者(m
或p
)后跟3位数字)。所以我要提取的第一件事是3位数,第二位是字符串。
我推出了以下方法(我意识到这可能不是最优/最好的方法):
my $marker = '^testImrr[a-zA-z_]+\d{3}_(off|(m|p)\d{3})$';
if ($str =~ m/$marker/)
{
print "1=$1 2=$2";
}
只有$1
具有有效结果(即我想要的最后一点信息),但$2
为空。关于如何在中间获得这3位数的任何想法?
答案 0 :(得分:5)
你快到了。
只是:
- 通过在(\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
你会得到:
function myFunction(x) {
x.classList.toggle("change");
$("#phone-1").toggle()
}
答案 1 :(得分:2)
您可以同时捕获两者,例如
if ($str =~ /(\d{3})_(off|(?:m|p)\d{3})$/ ) {
print "1=$1, 2=$2".$/;
}
您的示例也有两个捕获组(off|(m|p)\d{3}
和m|p
)。如果你是第一个文件名,对于第二个捕获组,由于匹配另一个分支,没有捕获任何内容。对于非捕获组,请使用(?:yourgroup)
。
答案 2 :(得分:1)
当简单的split
和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