将 javascript 转换为 PHP:数组和对象

converting javascript to PHP: array and objects

我想将以下 javascript 代码转换为 PHP 但我卡住了。 这是 javascript:

var string = "(Munich:0.1,Paris:0.2,(Cyprus:0.3,Brussels:0.4)Bern:0.5)Hamburg";

var ancestors = [];
var tree = {};
var tokens = string.split(/\s*(;|\(|\)|,|:)\s*/);
for (var i=0; i<tokens.length; i++) {
  var token = tokens[i];
  switch (token) {
    case '(': // new children
      var subtree = {};
      tree.children = [subtree];
      ancestors.push(tree);
      tree = subtree;
      break;
    case ',': // another branch
      var subtree = {};
      ancestors[ancestors.length-1].children.push(subtree);
      tree = subtree;
      break;
    case ')': // optional name next
      tree = ancestors.pop();
      break;
    case ':': // optional length next
      break;
    default:
      var x = tokens[i-1];
      if (x == ')' || x == '(' || x == ',') {
        tree.name = token;
      } else if (x == ':') {
        tree.length = parseFloat(token);
      }
  }
}

这个(变量树)的输出是:

{
  name: "Hamburg",
  children: [
    {name: "Munich", length: 0.1},
    {name: "Paris", length: 0.2},
    {
      name: "Bern",
      length: 0.5,
      children: [
        {name: "Cyprus", length: 0.3},
        {name: "Burssels", length: 0.4}
      ]
    }
  ]
}

我将其转换为 PHP 的尝试如下。但是输出是完全不同的。我认为这与 [] 和 {} 之间 javascript 的差异有关,其中一个创建数组,另一个创建对象。但是我无法让它工作。

$string = "(Munich:0.1,Paris:0.2,(Cyprus:0.3,Brussels:0.4)Bern:0.5)Hamburg";
$ancestors = array();
$tree = array();
$tokens = preg_split('/(:|\,|\(|\))/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$count = count($tokens);
for ($i=0; $i<$count; $i++) {    
    $token = $tokens[$i];    
    switch ($token) {
        case '(': // new children
            $subtree = array();
            $tree['children'] = $subtree;
            array_push($ancestors, $tree);
            $tree = $subtree;
            break;
        case ',': // another branch
            $subtree = array();
            array_push($ancestors[((count($ancestors))-1)]['children'],$subtree);
            $tree = $subtree;
            break;
       case ')': // optional name next
           $tree = array_pop($ancestors);
           break;
       case ':': // optional length next
           break;
       default:
           $x = $tokens[$i-1];
           if ($x == ')' || $x == '(' || $x == ',') {
               $tree['name'] = $token;
           } else if ($x == ':') {
               $tree['length'] = $token;
           }
    }    
}

非常感谢任何解决此问题的想法。

我重写了你的代码,它产生了正确的结果

<?php

$string = '(Munich:0.1,Paris:0.2,(Cyprus:0.3,Brussels:0.4)Bern:0.5)Hamburg';

$items = parse_code($string);

print_r($items);

function parse_code($string) {
    $data = [];

    if (preg_match_all('@(\((.*)\))*(\w+)(:([0-9.]+))*@', $string, $matches)) {
        foreach ($matches[2] as $n=>$item) {
            $node = [];

            $node['name'] = $matches[3][$n];

            if ($matches[5][$n]) {
                $node['length'] = $matches[5][$n];
            }

            $children = parse_code($matches[2][$n]);

            if (count($children)) {
                $node['children'] = $children;
            }

            $data[] = $node;
        }
    }

    return $data;
}

结果

Array
(
    [0] => Array
        (
            [name] => Hamburg
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Munich
                            [length] => 0.1
                        )

                    [1] => Array
                        (
                            [name] => Paris
                            [length] => 0.2
                        )

                    [2] => Array
                        (
                            [name] => Bern
                            [length] => 0.5
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [name] => Cyprus
                                            [length] => 0.3
                                        )

                                    [1] => Array
                                        (
                                            [name] => Brussels
                                            [length] => 0.4
                                        )

                                )

                        )

                )

        )

)

编辑:仅当您在当前级别有一个嵌套结构时,此代码才有效。