解析结构化和非结构化文本的混合

时间:2012-10-19 04:41:17

标签: php regex string

我需要解析文本块,其格式如下:

Today the weather is excellent bla bla bla.
<temperature>35</temperature>. 
I'm in a great mood today. 
<item>Desk</item>

我想解析这样的文本,并将其翻译成类似这样的数组:

$array[0]['text'] = 'Today the weather is excellent bla bla bla. ';
$array[0]['type'] = 'normalText';

$array[1]['text'] = '35';
$array[1]['type'] = 'temperature';

$array[2]['text'] = ". I'm in a great mood today.";
$array[2]['type'] = 'normalText';

$array[3]['text'] = 'Desk';
$array[3]['type'] = 'item';

基本上,我希望数组以与原始文本相同的顺序包含所有文本,但是分成类型:普通文本(意思是不在任何标签之间的东西),以及其他类型如温度, item,由文本所在的标签决定。

有没有办法做到这一点(即将文本分成普通文本和其他类型,使用正则表达式)或者我应该在幕后将文本转换为结构合理的文本,如:

<normal>Today the weather is excellent bla bla bla.</normal>
<temperature>35</temperature>.
<normal> I'm in a great mood today.</normal><item>Desk</item>

在尝试解析文本之前?

2 个答案:

答案 0 :(得分:3)

编辑:现在它完全符合预期!

<强>解决方案:

<?php

$code = <<<'CODE'
Today the weather is excellent bla bla bla.
<temperature>35</temperature>. 
I'm in a great mood today. 
<item>Desk</item>
CODE;

$result = array_filter(
    array_map(
        function ($element) {
            if (!empty($element)) {
                if (preg_match('/^\<([^\>]+)\>([^\<]+)\</', $element, $matches)) {
                    return array('text' => $matches[2],
                                 'type'    => $matches[1]);
                } else {
                    return array('text' => $element,
                                 'type'    => 'normal');
                }
            }
            return false;
        },
        preg_split('/(\<[^\>]+\>[^\<]+\<\/[^\>]+\>)/', $code, null, PREG_SPLIT_DELIM_CAPTURE)
    )
);

print_r($result);

<强>输出:

Array
(
    [0] => Array
        (
            [text] => Today the weather is excellent bla bla bla.

            [type] => normal
        )

    [1] => Array
        (
            [text] => 35
            [type] => temperature
        )

    [2] => Array
        (
            [text] => . 
I'm in a great mood today. 

            [type] => normal
        )

    [3] => Array
        (
            [text] => Desk
            [type] => item
        )

)

答案 1 :(得分:1)

尝试逐行阅读文本。你有2个案例。添加普通文本并添加具有特殊标记的文本。 将常规文本添加到变量时,请查找带有regexp的标记。

preg_match("/\<(\w)\>/", $line_from_text, $matches) 

匹配标记,()将保存单词以与$ matches中的数组一起使用。现在只需将文本添加到变量中,直到遇到结束标记。 希望这会有所帮助。