【问题标题】:Why doesn't this perl regex work为什么这个 perl 正则表达式不起作用
【发布时间】:2016-11-29 09:24:37
【问题描述】:
@matches = ( $filestr =~ /^[0-9]+\. (.+\n)*/mg );

我有一个已读入 filestr 的文件,但由于某种原因,上面的正则表达式应该匹配一行的开头,后跟一个数字、一个点、一个空格,然后是任意数量的行,后跟一个换行符(因此当有一行只有换行符时结束),似乎只是从文件中产生一些单行。

当我做类似的事情时

@matches = ( $filestr =~ /^[0-9]+\. .+\n/mg );

我正确匹配了一行。

当我这样做时

@matches = ( $filestr =~ /^[0-9]+\. .+\n.+\n/mg );

我匹配相同的单行,然后是一些看似无关的行。我的正则表达式有什么问题?

注意:正则表达式在这个正则表达式测试器中工作正常:https://regex101.com/,它在 perl 中不起作用。

例如,在本文中:

1. This should
match

2. This should too

3. This
one
also

正则表达式应该匹配

1. This should
match

2. This should too

3. This
one
also

【问题讨论】:

  • 仅供参考:当换行符起作用时,请考虑使用\R 而不是\n。但是,在这里你最好改变整个方法并逐行阅读,检查每个后续的。
  • 感谢您的建议。我刚刚尝试了 \R 但我得到了与 \n 相同的结果。
  • 您知道按照您建议的方式逐行检查的好方法吗?看来我基本上是手动拆分正则表达式。首先检查一行是否匹配 ^[0-9]+\。 , 然后检查一行是否与第一行的其余部分和所有后续行匹配 .+\n (直到我得到一行只有一个换行符的行,此时我必须重新启动)。
  • 您能否发布匹配正则表达式的示例行
  • 我只能建议像/^[0-9]+\..*?(?:\R{2}|\z)/gsm这样的正则表达式修复

标签: regex perl


【解决方案1】:

您的正则表达式是正确的。但是,您正在部分捕获结果。我建议您将整个匹配捕获到单个结果集中,这就是将其存储到@matches 的方式。

因此,正确的正则表达式将变为 /(^[0-9]+\. (?:.+\n)*)/gm。通过这种方式,您将匹配结果捕获到$1。把它包装成一个程序就可以了。

虽然,它会在不保留那些括号(...) 的情况下工作,因为默认情况下它需要$&(即整个匹配),除非你捕获任何东西。因此,请记住,在这些情况下,您应该使用 non-capturing group(?: ... ) 而不是捕获 group()

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $str = '
1. This should
match

2. This should too

3. This
one
also
';

my @matches = $str =~ /^([0-9]+\. (?:.+\n)*)/gm;

print Dumper(\@matches);

输出:

[
          '1. This should
match
',
          '2. This should too
',
          '3. This
one
also
'
        ];

【讨论】:

    【解决方案2】:

    在这种情况下,您应该逐段阅读,而不是逐行阅读。为此,您需要将 $/ 设置为空字符串。示例:

    use strict;
    use warnings;
    
    my @result;
    
    {
        local $/ = "";
        while (<DATA>) {
            chomp;
            push @result, $_ ;
            # or to filter paragraphs that don't start with a digit, use instead:
            # push @result, $_ if /^[0-9]+\./; 
        }
    }
    
    
    __DATA__
    1. This should
    match
    
    2. This should too
    
    3. This
    one
    also
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      相关资源
      最近更新 更多