简单的PHP字符串解析

时间:2011-05-01 02:52:03

标签: php string

我正在尝试使用PHP解析以下格式:

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

也许只是缺乏咖啡因,但我想不出一个获得花括号内容的好方法。

2 个答案:

答案 0 :(得分:1)

这是一个非常常见的解析任务,基本上你需要跟踪你可以处于的各种状态,并使用常量和函数调用的组合来维护它们。

以下是一些相当不优雅的代码:

<?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
                    (
                    )

                )

            )

        )

    )

)

你可能想要清理所有的空白区域,但是一些位置很好的装饰会为你排序。

答案 1 :(得分:0)

这可能不是大量内容的最佳解决方案,但它确实有效。

<?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 )