我正在做一些perl脚本,但是我在阅读文件时遇到了一些问题,而不是迭代正则表达式。
特别是文件超过多行,对于每一行,我需要提取一些值,我发布一个例子来更好地理解。
这是文件的示例行
1A OCC OCC 4B 5B 6B 7B 8B 9A
OCC OCC 12B 13B 14B OCC 16B 17B 18B OCC OCC
我需要匹配第一,第二,n ..,行separetly: 1A 4B 5B 6B 7B ...
除了OCC。
我写了这段代码:my $path="file.txt";
open (my $fh, "<", $path);
while(my $line = <$fh>)
{
for ($line =~/(\d{1,2}[A|B|C])/){
print " $1";
}
}
我获得的结果仅匹配在线上匹配的第一次出现。 1A 12B
如何扩展读取所有行并正确匹配内容?
打印结果仅供我的调试测试。
答案 0 :(得分:2)
要匹配所有出现的正则表达式,您需要使用/g
修饰符。
此外,由于for
的参数在列表上下文中计算,它将立即返回所有匹配,因此使用$1
将为每个匹配返回相同的值(最后一个);但你可以使用循环变量:
for ($line =~ /(\d{1,2}[ABC])/g) {
print " $_";
}
但是,通常用while
循环匹配,因为它会逐个返回匹配的部分,而不需要很长的匹配列表。在这里,您需要$1
,因为循环条件是在标量上下文中计算的:
while ($line =~ /(\d{1,2}[ABC])/g) {
print " $1";
}
注意:您的输入不包含|
,因此我将其从字符类中删除。
答案 1 :(得分:2)
您编写的匹配项会捕获一次并停止。因此for
循环超过(line =~ ...)
内的一个数字。
您可以使用/g
修饰符,这将使正则表达式继续前进并找到所有匹配项。如果将其分配给数组,则运算符位于列表上下文中,并返回所有匹配项
my @matches = $line =~ /\d{1,2}[A-C]/g;
在这里,您不需要捕捉括号,因为您进行了整场比赛。如有疑问,请添加它们。如果您只需要任何数字后跟任何字母,则可以使用/\d+\w+/g
代替。
我想再发几条评论。
请始终使用use warnings;
和use strict;
始终总是检查open
共
use warnings 'all';
use strict;
use feature qw(say);
my $path="file.txt";
open my $fh, "<", $path or die "Can't open $path: $!";
while (my $line = <$fh>)
{
my @matches = $line =~ /(\d{1,2}[A-C])/g;
say "@matches";
}
close $fh;