Parsing a string with recursive parentheses

后端 未结 1 1316
野性不改
野性不改 2020-12-19 17:46

I\'m trying to parse a string with the following structure in PHP:

a,b,c(d,e,f(g),h,i(j,k)),l,m,n(o),p

For example, a \"real\" string will

相关标签:
1条回答
  • 2020-12-19 18:01

    As Wiktor pointed out, this can be achieved with the help of a lexer. The following answer uses a class originally from Nikita Popopv, which can be found here.

    What it does

    It skims through the string and searches for matches as defined in the $tokenMap. These are defined as T_FIELD, T_SEPARATOR, T_OPEN and T_CLOSE. The values found are put in an array called $structure.
    Afterwards we need to loop over this array and build the structure out of it. As there can be multiple nestings, I chose a recursive approach (generate()).

    Demo

    A demo can be found on ideone.com.

    Code

    The actual code with explanations:

    // this is our $tokenMap
    $tokenMap = array(
        '[^,()]+'       => T_FIELD,     # not comma or parentheses
        ','             => T_SEPARATOR, # a comma
        '\('            => T_OPEN,      # an opening parenthesis
        '\)'            => T_CLOSE      # a closing parenthesis
    );
    
    // this is your string
    $string = "id,topic,member(name,email,group(id,name)),message(id,title,body)";
    
    // a recursive function to actually build the structure
    function generate($arr=array(), $idx=0) {
        $output = array();
        $current = null;
        for($i=$idx;$i<count($arr);$i++) {
            list($element, $type) = $arr[$i];
            if ($type == T_OPEN)
                $output[$current] = generate($arr, $i+1);
            elseif ($type == T_CLOSE)
                return $output;
            elseif ($type == T_FIELD) {
                $output[$element] = null;
                $current = $element;
            }
        }
        return $output;
    }
    
    $lex = new Lexer($tokenMap);
    $structure = $lex->lex($string);
    
    print_r(generate($structure));
    
    0 讨论(0)
提交回复
热议问题