的工作,因为你的输入数据被很好地格式化您可以创建一个非常简单的递归后裔解析器 - 即使没有那么多的递归参与其中。或者只是一个简单的堆栈:
$props = array_filter(array_map('trim', explode("\n", $prop)));
$stack = [$node = $xml = new SimpleXMLElement('<root/>')];
foreach ($props as $str)
{
if ($str === '}') {
array_pop($stack);
$node = end($stack);
continue;
}
if (preg_match('~^(\w+) {$~', $str, $matches)) {
$node = $stack[] = $node->addChild($matches[1]);
continue;
}
if (preg_match('~^(\w+):\s*(.*)$~', $str, $matches)) {
$node->addChild($matches[1], htmlspecialchars($matches[2]));
continue;
}
throw new UnexpectedValueException(sprintf('Unable to parse: "%s"', $str));
}
$xml->asXML('php://output');
你的第二个例子(以前失踪),然后是(美化)输出:
<?xml version="1.0"?>
<root>
<button>
<large>
<bond>
<width>10px;</width>
<height>10px;</height>
</bond>
<style>
<background>
<color>#ffffff;</color>
<image>url(www.px.com/aui.png) -10px;</image>
<another>
<width>100px;</width>
<height>100px;</height>
</another>
</background>
</style>
</large>
<small>
<bond>
<width>10px;</width>
<height>10px;</height>
</bond>
<style>
<color>#fff;</color>
<border>1px solid #000;</border>
</style>
</small>
</button>
</root>
我建议你使用XML这里,因为它可以代表结构更好比不能有重复键的数组。
也可以使用递归函数调用而不是堆栈。但是这需要来包装输入流中的无倒带迭代器不会打破(或使用array_shift
,但我不喜欢那么多):
$parse = function($p, SimpleXMLElement $t) use (&$parse) {
foreach($p as $s) {
if ($s === '}') {
break;
}
if (preg_match('~^([^ ]+) {$~', $s, $m)) {
$p->next();
$parse($p, $t->addChild($m[1]));
continue;
}
if (preg_match('~^([^:]+):\s*(.*)$~', $s, $m)) {
$n = $t->addChild($m[1], htmlspecialchars($m[2]));
continue;
}
}
};
$props = array_filter(array_map('trim', explode("\n", $prop)));
$xml = new SimpleXMLElement('<root/>');
$parse(new NoRewindIterator(new ArrayIterator($props)), $xml);
$xml->asXML('php://output');
格式符合什么条件?实际上,如果这是CSS,那么数组不能工作,因为可能有重复的键。 – hakre 2013-04-07 11:44:35
这不适用于CSS。我会将它们用于我的应用程序属性,如配置等。上面的键只是示例。要阅读我使用'read('config.debugger.debug_mode');'的属性。我这样做是为了简化财产分配并简化财产的阅读。另外'read()'函数可以在任何地方使用,所以我不需要使用$ GLOBALS ['config'];谢谢。 – 2013-04-07 12:34:42
很高兴知道,看起来像CSS一样。当你问这个问题添加这样的上下文时,这也是一个好主意。例如。你可以使用第一个存在的东西,比如属性文件或yaml。甚至只是一个数组。至于你的解决方案:请把它从问题转移到答案。这是正确的方法,解决方案不属于这个问题。 – hakre 2013-04-07 12:37:11