How to parse a line and result in array - stuck

試著忘記壹切 提交于 2019-12-25 05:11:52

问题


Here's what I try to do :

isNumeric(right(trim(contract_id),1))

isNumeric
    right
        trim
            contract_id
        1

isNumeric(right(trim(contract_id),1), bob, george(five(four, two)))

isNumeric
    right
        trim
            contract_id
        1
    bob
    george
        five
            four
            two

So basiclly it take a line (let'say trim(var)) and will make an array of it (array(trim => array(var)).

I did try with regex and strpos but no result... I need help. Thanks.


回答1:


First off a descent parser will always give you better control.
A whole regex solution might enable you to skip errors or at least let you continue
and not crap out.

Your format is extremely simple, and an engine that can do internal recursion could at
least get you an outter match. Using language recursion, you could re-enter that regex
enabling you to parse the core.

I'm no php expert, but if it supports regex recursion and language level eval() you
will be able to inject an array construct into the source text.
Then eval the string to create an nested array image, complete with parameters.

I actually converted your text to an array in about 12 lines of Perl, but added to
it when it got interresting.

Here is a Perl sample. Its dumbed down so its readable. It might give you some inspiration to try it in php (if it can do these things). Like I said I'm no php expert.

  use Data::Dumper;

  my $str = '
    asdf("asg")
    isNumeric(right(trim(contract_id),1))
    var = \'aqfbasdn\'
    isNumeric(right(trim ( ,contract_id,),-1, j( ) ,"  ", bob, george(five(four, two))))
  ';

  my $func      = '\w+';           # Allowed characters (very watered down)
  my $const     = '[\w*&^+-]+';
  my $wspconst  = '[\w*&^+\s-]+';

  my $GetRx = qr~
    \s*
    (                       # 1 Recursion group
       (?:
           \s* ($func) \s* 
           [(]
              (?:  (?> (?: (?!\s*$func\s*[(] | [)] ) . )+ ) 
                 | (?1)                                         
              )*                                               
           [)]
       )
     )                                                 
  ~xs;

  my $ParseRx = qr~
    (                        # 1 Recursion group
       (?:
           \s* ($func) \s*                                    # 2 Function name
           [(]
           (                                                  # 3 Function core
              (?:  (?> (?: (?!\s*$func\s*[(] | [)] ) . )+ ) 
                 | (?1)                                         
              )*                                               
           )                                                   
           [)]
                                         # OR..other stuff
                                         # Note that this block of |'s is where               
                                         # to put code to parse constants, strings,
                                         # delimeters, etc ... Not much done, but
                                         # here is where that goes.
                                         # -----------------------------------------
         |  \s*["'] ($wspconst) ["']\s*      # 4,5 Variable constants
         | \s* ($const) \s* 
                                         # Lastly, accept empty parameters, if
         | (?<=,)                        # a comma behind us,
         | (?<=^)(?!\s*$)                # or beginning of a new 'core' if actually a paramater.
       )       
     )                                                 
  ~xs;

##
  print "Source string:\n$str\n";
  print "=======================================\n";
  print "Searching string for functions ...\n";
  print "=======================================\n\n";


  while ($str =~ /$GetRx/g) {
      print "------------------\nParsing:\n$1\n\n";
      my $res = parse_func($1);
      print "String to be eval()'ed:\n$res\n\n";

      my $hashref = eval $res.";";
      print "Hash from eval()'ed string:\n", Dumper( $hashref ), "\n\n";
  }

###
  sub parse_func
  {
      my ($core) = @_;
      $core =~ s/$ParseRx/ parse_callback($2, $3, "$4$5") /eg;
      return $core;
  }

  sub parse_callback
  {
      my ($fname, $fbody, $fconst) = @_;
      if (defined $fbody) {
          return "{'$fname'=>[" . (parse_func( $fbody )) . "]}";
      }
      return "'$fconst'"
  }

Output

Source string:

    asdf("asg")
    isNumeric(right(trim(contract_id),1))
    var = 'aqfbasdn'
    isNumeric(right(trim ( ,contract_id,),-1, j( ) ,"  ", bob, george(five(four, two))))

=======================================
Searching string for functions ...
=======================================

------------------
Parsing:
asdf("asg")

String to be eval()'ed:
{'asdf'=>['asg']}

Hash from eval()'ed string:
$VAR1 = {
          'asdf' => [
                      'asg'
                    ]
        };


------------------
Parsing:
isNumeric(right(trim(contract_id),1))

String to be eval()'ed:
{'isNumeric'=>[{'right'=>[{'trim'=>['contract_id']},'1']}]}

Hash from eval()'ed string:
$VAR1 = {
          'isNumeric' => [
                           {
                             'right' => [
                                          {
                                            'trim' => [
                                                        'contract_id'
                                                      ]
                                          },
                                          '1'
                                        ]
                           }
                         ]
        };


------------------
Parsing:
isNumeric(right(trim ( ,contract_id,),-1, j( ) ,"  ", bob, george(five(four, two))))

String to be eval()'ed:
{'isNumeric'=>[{'right'=>[{'trim'=>['' ,'contract_id','']},'-1',{'j'=>[ ]} ,'  ','bob',{'george'=>[{'five'=>['four','two']}]}]}]}

Hash from eval()'ed string:
$VAR1 = {
          'isNumeric' => [
                           {
                             'right' => [
                                          {
                                            'trim' => [
                                                        '',
                                                        'contract_id',
                                                        ''
                                                      ]
                                          },
                                          '-1',
                                          {
                                            'j' => []
                                          },
                                          '  ',
                                          'bob',
                                          {
                                            'george' => [
                                                          {
                                                            'five' => [
                                                                        'four',
                                                                        'two'
                                                                      ]
                                                          }
                                                        ]
                                          }
                                        ]
                           }
                         ]
        };


来源:https://stackoverflow.com/questions/10624370/how-to-parse-a-line-and-result-in-array-stuck

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!