我尝试在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的字段查询参数,允许客户端从复杂的对象集合中选择他想要的字段,并且我不想限制"深度&# 34;选择领域。
答案 0 :(得分:3)
正如Wiktor指出的那样,这可以在词法分子的帮助下实现。以下答案使用了最初来自Nikita Popopv的类,可以找到here。
它浏览字符串并搜索$tokenMap
中定义的匹配项。这些定义为T_FIELD
,T_SEPARATOR
,T_OPEN
和T_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));