PHP - 回显数组中标记的打开和关闭

时间:2018-02-04 16:55:01

标签: php html arrays json html-parsing

这里我有一个数组,里面有内容,它们是一个对象,两个或更多 - 取决于所需的标签;嵌套在多维数组中的第一个元素是文本输出,除非它是一个数组,那么数组中的第一个元素就是文本。

但是,数组中的其他内容是引用它们对应的HTML标记,例如:

read-only or active working

然而,在简单的模块中,我更希望内容不要经常重复这样的回答,例如:

    [1] => Array
    (
        [0] => bo          <====== Text to output
        [1] => bold        <====== tag to be within
    )

而输出应该是:

This is a test <b>bo</b><i><b>ld</b></i><i>,</i> <u><i>u</i></u><u>nderline</u> ...

到目前为止,这是我的PHP代码......

This is a test<b>bo<i>ld</i></b><i>, <u>u</u></i><u>nderline</u> ...

如果需要,这是数组(采用JSON格式!):

$use = array();
$base = "";
foreach ($build as $part => $data) {
//  print_r($use);
    if(!is_array($data)){
        $base .= $data;
    } else {
        $text = array_shift($data);
        if(!is_array($data[0])){
            $data = array($data[0]);
        } else {
            $data = $data[0];
        }
        $removed = array_diff($use,$data);

        foreach (($data) as $tag) {
            if (in_array($tag, array_diff($use,$data))) {
                $base .= "<\/" . $tag . ">";
            } elseif(!in_array($tag, $use)){
                $base .= "<" . $tag . ">";
                array_push($use, $tag);
            }
        }
        $use = $data;
        $base .= $text; 
    }
}
print_r($base);

非常感谢任何帮助......谢谢!

2 个答案:

答案 0 :(得分:1)

老实说,我不确定这是否正是您正在寻找的。拥有一个完整的期望输出会很棒......但我相信这一点非常接近。我花了3个小时,所以最好是它。这是一个很好的问题,很难完成。

  

我做了print_r(htmlentities($base)),但您只需print_r($base)即可查看格式化结果。我这样做是因为用问题中提供的输出检查更容易。

     

另外,我修改了你的JSON,因为那里指定的一些标签不存在。例如,我为underline更改了u,为italic更改了i,为bold更改了b。替代方案是emstrong ...无论如何,这只是一个旁注。

<?php
$build = json_decode('["This is a test\nIncluding ",["bo","b"],["ld",["i","b"]],[", ","i"],["u",["u","i"]],["nderlined","u"],", ",["strike-through","strike"],", and ",["italic","i"],"\ntext:\n\n",["numbered lists",["u","strike","i","b"]],["\n",[]],"as well as",["\n",[]],["non ordered lists","http:\/\/test.com"],["\n",[]],"it works very well",["\n",[]],["try it","http:\/\/google.com"],"\n",["http:\/\/google.com",["b","http:\/\/google.com"]],"\n\n",["wow","b"],"\n",["lol","b"]]', true);
$used = [];
$base = '';
foreach($build as $data){
    if(is_array($data)){
        $text = array_shift($data);
        $tags = $data[0];
        if(!is_array($data[0])){
            $tags = [$data[0]];
        }
        $elements = '';
        $tagsToClose = array_diff($used, $tags);
        $changes = true;
        $i = 0;
        foreach($tagsToClose as $tag){
            while($changes){
                $changes = false;
                if($lastOpened != $tag){
                    $changes = true;
                    $elements .= '</'.$lastOpened.'>';
                    unset($used[$i++]);
                    $lastOpened = $used[$i];
                }
            }
            $elements .= '</'.$tag.'>';
            $key = array_search($tag, $used);
            unset($used[$key]);
        }
        foreach($tags as $tag){
            if(!in_array($tag, $used)){
                $elements .= '<'.$tag.'>';
                array_unshift($used, $tag);
                $lastOpened = $tag;
            }
        }
        $elements .= $text;
        $data = $elements;
    }
    $base .= $data;
}
unset($used);
$base .= '</'.$lastOpened.'>';
print_r(htmlentities($base));
?>

修改

以下是我得到的结果,以防万一你遇到麻烦测试或检查你的结果或其他什么:

  

This is a test Including <b>bo<i>ld</i></b><i>, <u>u</u></i><u>nderlined, </u><strike>strike-through, and </strike><i>italic text: <u><strike><b>numbered lists</b></strike></u></i> as well as <http://test.com>non ordered lists</http://test.com> it works very well <http://google.com>try it <b>http://google.com </b></http://google.com><b>wow lol</b>

答案 1 :(得分:0)

经过几个小时,这是我最终解决的问题:

$build = json_decode('["This is a test Including\u00a0",["bo","bold"],["ld",["italic","bold"]],[",\u00a0","italic"],["u",["underline","italic"]],["nderlined,\u00a0","underline"],"strike-through, and\u00a0",["italic text:\u00a0","italic"],"it works very well\u00a0try it\u00a0",["http:\/\/google.com",["bold","http:\/\/google.com"]],["\u00a0wow lol","bold"]]',true);
$standard = array("bold"=>"b","underline"=>"u","strike"=>"s","italic"=>"i","link"=>"a","size"=>null);
$lists = array("ordered"=>"ol","bullet"=>"ul");
$size = array("huge"=>"2.5em","large"=>"1.5em");

$base = "";
foreach($build as $part){
    $use = array();
    $tags = true;
    $len = 1;
    if(!is_array($part) or count($part) == 1){
        $text = $part;
        $tags = false;
        $part = array();
    } else {
        $text = array_shift($part);

        if(count($part) == 1){
            if(is_array($part[0])){
                $part = $part[0];
            }
        }
        if(!is_array($part)){
            $part = array($part);
        }
    }
    if($tags){
        foreach ($part as $tag) {
            if(!in_array($tag, array_keys($standard)) && !in_array($tag, array_keys($lists)) && !in_array($tag, array_keys($size))){
                $base .= '<a href="' . $tag . '" title="' . $tag . '" class="link">';
                $tag = "link";
            } elseif(in_array($tag, array_keys($size))){
                $base .= "<span style='font-size:" . $size[$tag] . "'>";
            } elseif(!in_array($tag, array_keys($lists))) {
                $base .= "<" . $standard[$tag] . ">";
            }
            array_push($use, $tag);
        }
        $base .= $text;
        foreach (array_reverse($part) as $tag) {
            if(!in_array($tag, array_keys($standard)) && !in_array($tag, array_keys($lists)) && !in_array($tag, array_keys($size))){
                $base .= '</a>';
            } elseif(in_array($tag, array_keys($size))){
                $base .= "</span>";
            } elseif (!in_array($tag, array_keys($lists))) {
                $base .= "</" . $standard[$tag] . ">";
            }
            array_push($use, $tag);
        }
    } else {
        $base .= $text;
    }
}
print_r($base);