是否可以使用DOMDocument拆分HTML?

时间:2014-08-22 16:15:50

标签: php html domdocument

使用 DOMDocument ,是否可以通过包含在标签中的文本和不包含标签的文本来拆分HTML块,同时保持订单?对不起,如果这没有意义。我的例子应该说清楚。

我们说我有以下HTML块:

text1<b style="color:pink">text2</b>text3<b>text4</b> <b style="font-weight:bold">text5</b>

是否可以创建一个数组:

array(
  [0] => text1 
  [1] => <b style="color:pink">text2</b>
  [2] => text3
  [3] => <b>text4</b>
  [4] => 
  [5] => <b style="font-weight:bold">text5</b>
)

下面是我当前使用正则表达式的工作解决方案来拆分HTML。

$tokens = preg_split('/(<b\b[^>]*>.*?<\/b>)/i', $html, null, PREG_SPLIT_DELIM_CAPTURE);

但是,我总是读到使用正则表达式解析HTML是一个坏主意,所以只是想知道是否有更好的方法。

2 个答案:

答案 0 :(得分:1)

感谢任何人给我一个评论(并迅速删除它)关于查看DOMDocument的子项。它帮助并允许我制定新的解决方案。

$tokens = array();

$dom = new DOMDocument();
$dom->loadHTML("<div>{$html}</div>");
$div = $dom->getElementsByTagName('div');
if ($div->length) {
    foreach($div->item(0)->childNodes as $node) {
        $tokens[] = ($node->nodeName === 'b') ? "<b>{$node->nodeValue}</b>" : $node->nodeValue;
    }
}

唯一的问题是,我不能直接用HTML包装文本,而无需构建它。

答案 1 :(得分:0)

嗯,您可以使用标记名称或传递*来获取所有标记。但是如果你有一个没有正确格式化的字符串,你可能会有意想不到的结果。

例如:

$x = 'text1<b style="color:pink">text2</b>text3<b>text4</b> <b style="font-weight:bold">text5</b>';

$dom = new DOMDocument();

$dom->loadHTML($x);

$array = array ();

foreach($dom->getElementsByTagName('*') as $node)
{
    if ($node->tagName != 'body' && $node->tagName != 'html'){
        $array[] = $dom->saveHTML($node);
    }
}

print_r($array);

会打印:

Array
(
    [0] => <p>text1<b style="color:pink">text2</b>text3<b>text4</b> <b style="font-weight:bold">text5</b></p>
    [1] => <b style="color:pink">text2</b>
    [2] => <b>text4</b>
    [3] => <b style="font-weight:bold">text5</b>
)

正如您所看到的,外部标记文本是dom尝试“更正”您的格式,并且可能会导致意外结果。

if(.. != 'body' .. . != 'html')的原因是因为dom自动放置这些标签。

但是,如果你的代码格式正确,那就好了,例如:

$x = '<span>text1</span><b style="color:pink">text2</b><span>text3</span><b>text4</b><b style="font-weight:bold">text5</b>';

输出:

Array
(
    [0] => <span>text1</span>
    [1] => <b style="color:pink">text2</b>
    [2] => <span>text3</span>
    [3] => <b>text4</b>
    [4] => <b style="font-weight:bold">text5</b>
)