Perl文件读取和RegEx匹配

时间:2017-01-27 09:42:51

标签: regex perl file-handling

我正在做一些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

如何扩展读取所有行并正确匹配内容?

打印结果仅供我的调试测试。

2 个答案:

答案 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;