2011-05-01 77 views
2

我试图解析用PHP的格式如下:简单的PHP字符串解析

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

也许只是缺少咖啡因,但我想不出获得的内容的一个体面的方式大括号。

+0

没有办法准确获得那样的内容。你需要更好的分隔符。但如果你真的想尝试,你需要基本上写一个从外部工作的算法,而不是从上到下。 – 2011-05-01 03:02:14

+0

嵌套*条目*是痛点。 – 2011-05-01 03:05:25

+0

你可以在顶部添加一个'<?php'和'token_get_all()'。迭代,跳过'<?php'和任何注释标记。然后将这些关键字与'join()'一起加入。 – alex 2011-05-01 03:23:43

回答

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

       ) 

      ) 

     ) 

    ) 

) 

你可能会想清理所有的空格,但是一些有利地位修剪会为你排序。

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) 
+0

那么,大多数情况下,如果您想要嵌套括号,只要把它扩展成一个可以回想起自己或类似的功能。 – robx 2011-05-01 03:48:09