Regex Group in Perl: how to capture elements into array from regex group that matches unknown number of/multiple/variable occurrences from a string?

前端 未结 9 2153
遇见更好的自我
遇见更好的自我 2020-12-04 10:10

In Perl, how can I use one regex grouping to capture more than one occurrence that matches it, into several array elements?

For example, for a string:



        
9条回答
  •  死守一世寂寞
    2020-12-04 10:37

    A bit over the top maybe, but an excuse for me to look into http://p3rl.org/Parse::RecDescent. How about making a parser?

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use Parse::RecDescent;
    
    use Regexp::Common;
    
    my $grammar = <<'_EOGRAMMAR_'
    INTEGER: /[-+]?\d+/
    STRING: /\S+/
    QSTRING: /$Regexp::Common::RE{quoted}/
    
    VARIABLE: /var\d+/
    VALUE: ( QSTRING | STRING | INTEGER )
    
    assignment: VARIABLE "=" VALUE /[\s]*/ { print "$item{VARIABLE} => $item{VALUE}\n"; }
    
    startrule: assignment(s)
    _EOGRAMMAR_
    ;
    
    $Parse::RecDescent::skip = '';
    my $parser = Parse::RecDescent->new($grammar);
    
    my $code = q{var1=100 var2=90 var5=hello var3="a, b, c" var7=test var8=" haha \" heh " var3=hello};
    $parser->startrule($code);
    

    yields:

    var1 => 100
    var2 => 90
    var5 => hello
    var3 => "a, b, c"
    var7 => test
    var8 => " haha \" heh "
    var3 => hello
    

    PS. Note the double var3, if you want the latter assignment to overwrite the first one you can use a hash to store the values, and then use them later.

    PPS. My first thought was to split on '=' but that would fail if a string contained '=' and since regexps are almost always bad for parsing, well I ended up trying it out and it works.

    Edit: Added support for escaped quotes inside quoted strings.

提交回复
热议问题