使用 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是一个坏主意,所以只是想知道是否有更好的方法。
答案 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>
)