PHP рекурсивная функция для преобразования вложенной {} разделенной строки в массив - PullRequest
1 голос
/ 24 июня 2019

Я пытаюсь построить рекурсивную функцию в php, которая берет строку со вложенными значениями {} и преобразует ее во вложенный массив. Есть ли встроенные функции, которые могут просто разделить это?

Также {скобки всегда будут в одной строке с ключом, т. Е. (Main {), а не Main \ n {.

Отступы также всегда будут постоянными.

Пример того, что я ищу ниже.

  Main{
    NetworkAccess 1; 
    MaxCPE 6; 
    MaxClassifiers 20; 
    GlobalPrivacyEnable 1; 
    BaselinePrivacy{
      AuthTimeout 10; 
      ReAuthTimeout 10; 
      AuthGraceTime 600; 
      OperTimeout 10; 
      ReKeyTimeout 10; 
      TEKGraceTime 600; 
      AuthRejectTimeout 60; 
      SAMapWaitTimeout 1; 
      SAMapMaxRetries 4; 
    }
    UsServiceFlow{
      UsServiceFlowRef 1; 
      QosParamSetType 7; 
      TrafficPriority 2; 
      MaxRateSustained 1000000; 
      SchedulingType 2; 
      MaxTrafficBurst 8000; 
      MaxConcatenatedBurst 8000; 
    }
    DsServiceFlow{
      DsServiceFlowRef 101; 
      QosParamSetType 7; 
      TrafficPriority 2; 
      MaxRateSustained 10000000; 
    }
  }

Array
(
    [Main] => Array
        (
            [NetworkAccess] => 1
            [MaxCPE] => 6
            [MaxClassifiers] => 20
            [GlobalPrivacyEnable] => 1
            [BaselinePrivacy] => Array
                (
                    [AuthTimeout] => 10
                    [ReAuthTimeout] => 10
                    [AuthGraceTime] => 600
                    [OperTimeout] => 10
                    [ReKeyTimeout] => 10
                    [TEKGraceTime] => 600
                    [AuthRejectTimeout] => 60
                    [SAMapWaitTimeout] => 1
                    [SAMapMaxRetries] => 4
                )

            [UsServiceFlow] => Array
                (
                    [UsServiceFlowRef] => 1
                    [QosParamSetType] => 7
                    [TrafficPriority] => 2
                    [MaxRateSustained] => 1000000
                    [SchedulingType] => 2
                    [MaxTrafficBurst] => 8000
                    [MaxConcatenatedBurst] => 8000
                )

            [DsServiceFlow] => Array
                (
                    [DsServiceFlowRef] => 101
                    [QosParamSetType] => 7
                    [TrafficPriority] => 2
                    [MaxRateSustained] => 10000000
                )

        )

)

Ответы [ 2 ]

2 голосов
/ 24 июня 2019

JSON был бы лучше, но это будет сложнее, так как ему не нравятся конечные запятые, где они не нужны (PHP не возражает).

$string = "[".str_replace(['{', '}', ';'], ['[', '],', ','], $string)."]";
$string =  preg_replace('/([a-z]+)/i', '"$1" =>', $string);
eval("\$result = $string;");
print_r($result);
0 голосов
/ 25 июня 2019

Другим вариантом для ваших текущих данных и с согласованными фигурными скобками может быть использование рекурсивной функции, использующей ссылки, отслеживающие текущий и родительский элементы.

Разнесение на новой строке и передача этого массива какотправная точка.Для каждой итерации возьмите первую с вершины, используя array_shift , которая вернет ноль, если массив пуст.

Если последний символ - {, текущий будет родительскими установить новый массив в качестве текущего для следующей итерации.

Если единственным символом является }, используйте родительский элемент для следующей итерации.

Например:

function processItems($items, &$current, &$parent) {
    $item =  trim(array_shift($items));
    if ($item) {

        if (substr($item, -1) === '{') {
            $key = rtrim($item, '{');
            $current[$key] = [];
            processItems($items, $current[$key], $parent);
            return;
        }

        if (trim($item) === '}') {
            processItems($items, $parent, $parent);
            return;
        }

        $parts = explode(' ',  $item);
        $current[$parts[0]] = rtrim($parts[1], ';');

        processItems($items, $current, $parent);
    }
}

$curr = [];
processItems(explode("\n", $data), $curr, $curr);

print_r($curr);

Результат

Array
(
    [Main] => Array
        (
            [NetworkAccess] => 1
            [MaxCPE] => 6
            [MaxClassifiers] => 20
            [GlobalPrivacyEnable] => 1
            [BaselinePrivacy] => Array
                (
                    [AuthTimeout] => 10
                    [ReAuthTimeout] => 10
                    [AuthGraceTime] => 600
                    [OperTimeout] => 10
                    [ReKeyTimeout] => 10
                    [TEKGraceTime] => 600
                    [AuthRejectTimeout] => 60
                    [SAMapWaitTimeout] => 1
                    [SAMapMaxRetries] => 4
                )

        )

    [UsServiceFlow] => Array
        (
            [UsServiceFlowRef] => 1
            [QosParamSetType] => 7
            [TrafficPriority] => 2
            [MaxRateSustained] => 1000000
            [SchedulingType] => 2
            [MaxTrafficBurst] => 8000
            [MaxConcatenatedBurst] => 8000
        )

    [DsServiceFlow] => Array
        (
            [DsServiceFlowRef] => 101
            [QosParamSetType] => 7
            [TrafficPriority] => 2
            [MaxRateSustained] => 10000000
        )

)

Php demo

...