Matching balanced parenthesis in Perl regex

前端 未结 6 1687
后悔当初
后悔当初 2021-01-12 08:52

I have an expression which I need to split and store in an array:

aaa=\"bbb{ccc}ffffd\" { aa=\"bb,cc\" { a=\"b\", c=\"d\" } }, aaa=\"bbb{}\" { aa=\"b}b\" }, aa         


        
6条回答
  •  滥情空心
    2021-01-12 09:38

    I agree with Scott Rippey, more or less, about writing your own parser. Here's a simple one:

    my $in = 'aaa="bbb{ccc}ffffd" { aa="bb,cc" { a="b", c="d" } }, ' .
             'aaa="bbb{}" { aa="b}b" }, ' .
             'aaa="bbb,ccc"'
    ;
    
    my @out = ('');
    
    my $nesting = 0;
    while($in !~ m/\G$/cg)
    {
      if($nesting == 0 && $in =~ m/\G,\s*/cg)
      {
        push @out, '';
        next;
      }
      if($in =~ m/\G(\{+)/cg)
        { $nesting += length $1; }
      elsif($in =~ m/\G(\}+)/cg)
      {
        $nesting -= length $1;
        die if $nesting < 0;
      }
      elsif($in =~ m/\G((?:[^{}"]|"[^"]*")+)/cg)
        { }
      else
        { die; }
      $out[-1] .= $1;
    }
    

    (Tested in Perl 5.10; sorry, I don't have Perl 5.8 handy, but so far as I know there aren't any relevant differences.) Needless to say, you'll want to replace the dies with something application-specific. And you'll likely have to tweak the above to handle cases not included in your example. (For example, can quoted strings contain \"? Can ' be used instead of "? This code doesn't handle either of those possibilities.)

提交回复
热议问题