将命令输出解析为数组,按空格结

时间:2017-09-07 15:08:48

标签: php

我正在使用命令行输出,它给出了以下输出:

| mainknot
|   knot_a
|     subknot_a_a
|       point_a_a_1
|       point_a_a_2
|     subknot_a_b
|       point_a_b_1
|       point_a_b_2
|   knot_b
|     subknot_b_a
|       point_b_a_1
|       point_b_a_2
|     subknot_b_b
|       point_b_b_1
|       point_b_b_2

如何将它现在放到数组或对象中:

$array['mainknot']['knot_a']['subknot_a_a']['point_a_a_1']
$array['mainknot']['knot_a']['subknot_a_a']['point_a_b_1']
$array['mainknot']['knot_a']['subknot_a_b']...

输出带有管道符号,除第一行外还有两个空格。只有一个空间

1 个答案:

答案 0 :(得分:0)

拍好。这比我应该花的时间更长,它绝对可以优化。我会尝试尽可能地记录代码。

http://sandbox.onlinephpfunctions.com/code/ad55e9accfb746c274e0a94d4c3eef8df779defb

<?php
$input = "| mainknot
|   knot_a
|     subknot_a_a
|         point_a_a_1
|         point_a_a_2
|     subknot_a_b
|         point_a_b_1
|         point_a_b_2
|         point_a_b_3
|   knot_b
|     subknot_b_a
|         point_b_a_1
|         point_b_a_2
|     subknot_b_b
|         point_b_b_1
|         point_b_b_2
|         point_b_b_3
";

// Split the string into an array so we can loop over it
$items = explode('|', $input);
$length = count($items);

// Reverse it and start from the bottom and work our way up the tree
$backwards = array_reverse($items);

// The final array containing the desired output
$final = [];

// Loop over each item starting from the bottom
// Don't trim any spaces yet because we use them to determine parent/child relationships
for($i = 0; $i < $length; $i++) {

    // Get the current item
    $current = $backwards[$i];

    // Get the previous item so we can compare it to the current item
    $down = ($i == 0)
        ? $backwards[$i]
        : $backwards[$i-1];

    // This main loop represent the "leaves" of tree
    // We don't want to add any leaves that have children... because... they aren't leaves ;)
    if (spaces($down) > spaces($current)) {
        continue;
    }

    // This is our first leaf. Add it to the final output
    $final[$i][] = trim($current);

    // This is a flag that stores the number of spaces a parent has.
    // We don't want to add parents of the same level.
    // BAD:
    /*
        |   knot_b
        |     subknot_b_a
        |     subknot_b_b
        |         point_b_b_3
    */
    $parentSpaces = 0;

    // Now, work ouy way up the tree and add parents to final output
    for($k = $i+1; $k < $length; $k++) {

        // The next item up the tree
        $up = $backwards[$k];

        // Make sure we don't add any blank items to the final output
        if (trim($up) == '') continue;

        // Find the parent. It will have fewer spaces than the current item. 
        // Also, once we've found a parent, ignore any other parents at the same level.
        if (spaces($up) < spaces($current) && ($parentSpaces == 0 || $parentSpaces > spaces($up))) {

            // Set the parent flag
            $parentSpaces = spaces($up);

            // Add the parent to the final output
            $final[$i][$k] = trim($up);
        }
    }

    // Now reverse the final output so "mainknot" is at the top
    krsort($final[$i]);
}

// Helper function to count spaces
function spaces($input) {
    return substr_count($input, ' ');
}

// Reverse the array back to its original direction
$final = array_reverse($final);

// Tada!
print_r($final);