【问题标题】:Perl File Reading and RegEx MatchingPerl 文件读取和正则表达式匹配
【发布时间】:2017-06-12 22:54:09
【问题描述】:

我正在编写一个小 perl 脚本,但我在读取文件时遇到了一些问题,而不是遍历正则表达式。

特别是文件超过多行,对于每一行,我需要提取一些值,我发布一个示例以便更好地理解。

这是文件的示例行

            1A    OCC OCC  4B  5B  6B  7B  8B    9A
      OCC OCC    12B 13B 14B OCC 16B 17B 18B   OCC OCC

我需要分别匹配第一、第二、n.. 行: 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

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

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

【问题讨论】:

    标签: regex perl file-handling


    【解决方案1】:

    要匹配所有出现的正则表达式,您需要使用/g 修饰符。

    此外,由于for 的参数是在列表上下文中评估的,它会一次返回所有匹配项,因此使用$1 会为每个匹配项返回相同的值(最后一个);但你可以使用循环变量:

    for ($line =~ /(\d{1,2}[ABC])/g) {
        print " $_";
    }
    

    但是,通常使用while 循环匹配匹配,因为它会一一返回匹配的部分,而不需要一长串匹配。在这里,您需要$1,因为循环条件是在标量上下文中评估的:

    while ($line =~ /(\d{1,2}[ABC])/g) {
        print " $1";
    }
    

    注意:您的输入不包含|,因此我将其从字符类中删除。

    【讨论】:

      【解决方案2】:

      您编写的匹配捕获一次然后停止。所以for 循环超过了(line =~ ...) 内的那个数字。

      您可以改为使用/g 修饰符,这将使正则表达式继续运行并找到所有匹配项。如果将其分配给数组,则运算符位于 list 上下文中,它会返回所有匹配项

      my @matches = $line =~ /\d{1,2}[A-C]/g;
      

      这里你不需要捕获括号,因为你拿了整场比赛。如有疑问,请添加它们。如果您只需要任何数字后跟任何字母,则可以改用/\d+\w+/g

      我想多做几个cmets。

      • 始终使用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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 1970-01-01
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        • 2011-08-04
        • 1970-01-01
        相关资源
        最近更新 更多