Простой анализ строки PHP - PullRequest
2 голосов
/ 01 мая 2011

Я пытаюсь проанализировать следующий формат с помощью PHP:

// This is a comment
{
this is an entry
}
{
this is another entry
}
{
entry
{entry within entry}
{entry within entry}
}

Возможно, это просто недостаток кофеина, но я не могу придумать приличный способ получить содержимое фигурных скобок.

Ответы [ 2 ]

1 голос
/ 03 мая 2011

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

Вот некоторый довольно неэффективный кодэто делает именно это:

<?php

$input = file_get_contents('input.txt');

define('STATE_CDATA', 0);
define('STATE_COMMENT', 1);

function parseBrace($input, &$i)
{
    $parsed = array(
        'cdata' => '',
        'children' => array()
    );
    $length = strlen($input);
    $state = STATE_CDATA;
    for(++$i; $i < $length; ++$i) {
        switch($input[$i]) {
            case '/':
                if ('/' === $input[$i+1]) {
                    $state = STATE_COMMENT;
                    ++$i;
                } if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
                break;
            case '{':
                if (STATE_CDATA === $state) {
                    $parsed['children'][] = parseBrace($input, $i);
                }
                break;
            case '}':
                if (STATE_CDATA === $state) {
                    break 2; // for
                }
                break;
            case "\n":
                if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
                $state = STATE_CDATA;
                break;
            default:
                if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
        }
    }
    return $parsed;
}

function parseInput($input)
{
    $parsed = array(
        'cdata' => '',
        'children' => array()
    );
    $state = STATE_CDATA;
    $length = strlen($input);
    for($i = 0; $i < $length; ++$i) {
        switch($input[$i]) {
            case '/':
                if ('/' === $input[$i+1]) {
                    $state = STATE_COMMENT;
                    ++$i;
                } if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
                break;
            case '{':
                if (STATE_CDATA === $state) {
                    $parsed['children'][] = parseBrace($input, $i);
                }
                break;
            case "\n":
                if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
                $state = STATE_CDATA;
                break;
            default:
                if (STATE_CDATA === $state) {
                    $parsed['cdata'] .= $input[$i];
                }
        }
    }
    return $parsed;
}

print_r(parseInput($input));

Это приводит к следующему выводу:

Array
(
    [cdata] =>




    [children] => Array
    (
        [0] => Array
        (
            [cdata] =>
this is an entry

            [children] => Array
            (
            )

        )

        [1] => Array
        (
            [cdata] =>
this is another entry

            [children] => Array
            (
            )   

        )

        [2] => Array
        (
            [cdata] => 
entry



            [children] => Array
            (
                [0] => Array
                (
                    [cdata] => entry within entry
                    [children] => Array
                    (
                    )


                )

                [1] => Array
                (
                    [cdata] => entry within entry
                    [children] => Array
                    (
                    )

                )

            )

        )

    )

)

Возможно, вы захотите очистить все пустые места, но некоторые хорошо расположенные обрезки будут сортировать это для вас.

0 голосов
/ 01 мая 2011

Возможно, это не лучшее решение для большого количества контента, но оно работает.

<?php
        $text = "I am out of the brackets {hi i am in the brackets} Back out { Back in}";
        print $text . '<hr />';

        $tmp = explode("{",$text);
        $tmp2 = array();
        $wantedText = array();
        for($i = 0; $i < count($tmp); $i++){
                if(stristr($tmp[$i],"}")){
                    $tmp2 = explode("}",$tmp[$i]);
                    array_push($wantedText,$tmp2[0]);
                }
        }
        print_r($wantedText);
    ?>

Результаты:

Array ( [0] => hi i am in the brackets [1] => Back in )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...