我正在尝试使用PHP解析以下格式:
// This is a comment
{
this is an entry
}
{
this is another entry
}
{
entry
{entry within entry}
{entry within entry}
}
也许只是缺乏咖啡因,但我想不出一个获得花括号内容的好方法。
答案 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 )