使用PHP将复杂字符串解析为父/子数组
下面是一个字符串示例使用PHP将复杂字符串解析为父/子数组,php,parsing,Php,Parsing,下面是一个字符串示例 a (b, c(d and/or e, f, g), h, i[j, k]), l (m, n(o, p[q, r{s or t,u}, v]), w) 我需要将其解析为如下内容: { -a -b -c -d -and/or -e -f -g -h -i -j -k -l -m -n -o
a (b, c(d and/or e, f, g), h, i[j, k]), l (m, n(o, p[q, r{s or t,u}, v]), w)
我需要将其解析为如下内容:
{
-a
-b
-c
-d
-and/or
-e
-f
-g
-h
-i
-j
-k
-l
-m
-n
-o
-p
-q
-r
-s
-t
-or
-u
-v
-w
}
我开始玩一些正则表达式,但很快就变丑了。有什么建议吗
谢谢。我不知道你的规则,但这段代码基本上可以完成这项工作
<?php
$string = 'a (b, c(d and/or e, f, g), h, i[j, k]), l (m, n(o, p[q, r{s or t,u}, v]), w)';
$indentLevel = 0;
$out = '';
echo '{'."\n";
// Split string into array of characters (AFAIK, that is basically how every parser works out there) and iterate over it
foreach (str_split($string) as $x) {
// Determine if this character is string terminator or not
$isTerminator = in_array($x, array(' ', ',', '(', '[', '{', ')', ']', '}'));
// Output, because of string terminator, but only if output has something in it
if ($isTerminator && strlen($out) > 0) {
echo str_repeat("\t", $indentLevel).'-'.$out."\n";
$out = '';
}
// Add to output (multiple character string support), if this is not string terminator
elseif (!$isTerminator) {
$out .= $x;
}
// Increase indent, because of brackets
if (in_array($x, array('(', '[', '{'))) {
$indentLevel++;
}
// Decrease indent, because of brackets
elseif (in_array($x, array(')', ']', '}'))) {
$indentLevel--;
}
// This is how you can tell that there is bracket count mismatch
if ($indentLevel < 0) {
die('Syntax error');
}
}
echo '}'."\n";
没有赢得任何选美比赛,但工作:
<?php
$s = 'a (b, c(d and/or e, f, g), h, i[j, k]), l (m, n(o, p[q, r{s or t,u}, v]), w)';
$chars = str_split($s);
$sep = array(',', ' ');
$open = array('(', '[', '{');
$close = array(')', ']', '}');
function parse($s)
{
global $sep, $open, $close;
$chars = str_split($s);
$arr = array();
$collect = '';
for ($i = 0; $i < count($chars); $i++) {
$c = $chars[$i];
if (in_array($c, $open)) {
$parens = 1;
$inner = '';
do {
$i++;
$ch = $chars[$i];
if (in_array($ch, $open)) {
$parens++;
} elseif (in_array($ch, $close)) {
$parens--;
}
if ($parens > 0) {
$inner .= $ch;
}
} while ($parens > 0);
if ($collect) {
$arr[] = '-'.$collect;
}
$arr[] = parse($inner);
$collect = '';
continue;
}
if (in_array($c, $sep)) {
if ($collect == '') {
continue;
}
$arr[] = '-'.$collect;
$collect = '';
} else {
$collect .= $c;
}
}
if ($collect) {
$arr[] = '-'.$collect;
}
return $arr;
}
print_r(parse($s));
这不是必然的结果。有时使用(),然后使用{},然后使用[]…;-)除了DOM提到的,要创建解析器,还需要定义解析器应该使用的精确规则。没有这些规则,没有人能正确回答你的问题。现在,我们只能猜测你想要实现的是什么。多姆,我知道它们是不一致的@Deele,我正在将成分列表解析为父/子结构。顶级项可以有嵌套的子项包装在()、[]或{}中。在大多数情况下,结构将是level1(level2[level3{level4}])@user3734597查看答案,不要忘记将适合您的答案标记为最佳答案,这样这个问题就可以结束了。这并不完全是OP要求的,但因为OP问题含糊不清,我不会降低这个答案的分数。输出格式是这之后的另一个步骤。我猜他只想要解析器。