【问题标题】:Using multiline regexps in Perl 5在 Perl 5 中使用多行正则表达式
【发布时间】:2015-06-10 04:55:55
【问题描述】:

我阅读了有关在 Perl 5 中使用多行正则表达式的手册,但仍然无法弄清楚为什么以下内容不能按预期工作:

#!/usr/bin/perl

use v5.20;

my $s = <<'ENDSTR';
aaa       : AAA
bbb       : BBB
ccc       : CCC
ENDSTR

my $m = 'bbb';

my $a = $s =~ s/.*^$m *: (.*?)$.*/$1/rsm;
my $b = $s =~ s/[.\n]*?^$m *: (.*)$[.\n]*/$1/rm;

print "a: $a\n";
print "b: $b\n";

程序的预期输出是

a: BBB
b: BBB

但是这些正则表达式会产生:

a: BBB
ccc       : CCC

b: aaa       : AAA
bbb       : BBB
ccc       : CCC  

如何更正这些正则表达式以获得所需的匹配?

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    在 perlmonks.org 上,有人建议我使用正确的变体:

    my $a = $1 if  $s =~ s/^$m *: (.*?)$/$1/rsm;
    my $b = $1 if  $s =~ s/^$m *: (.*)$/$1/rm;
    

    【讨论】:

      【解决方案2】:

      使用 s 标志,您允许 .元字符以匹配行尾。删除它或将正则表达式末尾的 .* 更改为 .*?

      【讨论】:

        【解决方案3】:

        我认为用\s*:\s*\n 分割该字符串可能更容易。您可以使用输出非常轻松地构建散列,但如果您的一个字符串中有:,而您的正则表达式有,这种方法将不起作用。以下代码适用于我:

        #!/usr/bin/perl
        
        use v5.20;
        
        my $s = <<'ENDSTR';
        aaa       : AAA
        bbb       : BBB
        ccc       : CCC
        ENDSTR
        
        my %hash = split(/(\s*:?\s*|\n)/, $s);
        say $hash{'bbb'};
        

        如果您尝试解析该格式的数据,您应该尝试使用Config::Generalcan parse a simple configuration file format 与您所拥有的非常相似,但也支持 cmets、block 和其他很酷的东西。

        【讨论】:

        • 你是对的,解析这样一个简单的字符串正则表达式根本不需要。但这个字符串仅用于多行正则表达式如何工作的简单示例。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多