php - 使用递归括号解析字符串

标签 php regex recursion

我正在尝试在 PHP 中解析具有以下结构的字符串:

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

例如,一个“真正的”字符串将是:

id,topic,member(name,email,group(id,name)),message(id,title,body)

我的最终结果应该是一个数组:

[
   id => null,
   topic => null
   member => [
      name => null,
      email => null,
      group => [
         id => null,
         name => null
      ]
   ],
   message => [
      id => null,
      title => null,
      body => null
  ]
]

我试过递归正则表达式,但完全迷路了。 我在迭代字符串字符方面取得了一些成功,但这似乎有点“过于复杂”,我确信这是正则表达式可以处理的事情,我只是不知道如何处理。

目的是为REST API解析一个字段查询参数,让客户端从一个复杂的对象集合中选择他想要的字段,我不想限制字段选择的“深度”。

最佳答案

正如 Wiktor 所指出的,这可以在词法分析器的帮助下实现。以下答案使用了最初来自 Nikita Popopv 的类,可以在 here 中找到。 .

它做什么

它浏览字符串并搜索 $tokenMap 中定义的匹配项。它们被定义为 T_FIELDT_SEPARATORT_OPENT_CLOSE。找到的值放在一个名为 $structure 的数组中。
之后我们需要遍历这个数组并从中构建结构。由于可以有多个嵌套,我选择了递归方法 (generate())。

演示

A demo can be found on ideone.com .

代码

带解释的实际代码:

// 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));

关于php - 使用递归括号解析字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35426793/

相关文章:

c - 正值输入 C

java - 如何在 Java 中使用递归获取 goldenRatio?

php - PHP 上的 JSON 编码和解码

php - 更改 mysql -joomla 中的文件名并存储在数据库中具有唯一的名称?

php - 如何在 PHP 中使用 JavaScript 变量?

regex - 使用perl在多个蛋白质序列中查找回文(完美回文)

php - 如何使用 PHP 或 HTML 在浏览器中查看/打开 word 文档

mysql - 为什么不 [ :blank:] work in MySQL

javascript - 使 str.index() 只匹配整个单词

c++ - 查找给定字符串的所有交错,这些交错可以由保留字符顺序的第一个和第二个字符串的所有字符组成