You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则表达式解析HTML时如何优先匹配最深层级的列表节点

解决方案1:使用正则负向断言匹配最内层节点

你可以通过负向零宽断言限制匹配的列表内部不包含同级的列表标签,就能直接命中最深层级的节点,循环处理即可实现从深到浅的解析:

$text = '
<ol>
    <li>
        <ul>
            <li>aaa</li>
            <li>bbb</li>
        </ul>
    </li>
    <li>fff</li>
    <li>
        <ol>
            <li>ccc</li>
            <li>ddd</li>
        </ol>
    </li>
</ol>
';

$processedContent = $text;
$sortList = [];
// 匹配不包含子ol/ul的最内层列表
while (preg_match('/<([ou]l)\b[^>]*>(?:(?!<\/?\1\b).)*<\/\1>/mis', $processedContent, $match)) {
    $sortList[] = $match[0];
    // 替换已处理的节点,避免重复匹配
    $processedContent = str_replace($match[0], '', $processedContent);
}

// 输出顺序为从最深到最浅,第一个元素就是你要的内层ol
print_r($sortList);

解决方案2:使用DOM扩展解析(更稳定)

正则处理嵌套HTML结构存在较多边界情况,仅适合结构非常固定的简单场景,正式项目更推荐用PHP原生DOM扩展解析,DOM本身是树状结构,只要按节点深度倒序排序就能直接得到从深到浅的列表:

$dom = new DOMDocument();
// 关闭HTML语法报错提示
libxml_use_internal_errors(true);
$dom->loadHTML($text);
libxml_clear_errors();

$xpath = new DOMXPath($dom);
// 查询所有ol和ul节点
$allLists = $xpath->query('//ol | //ul');
$listWithDepth = [];

foreach ($allLists as $listNode) {
    // 计算节点深度
    $depth = 0;
    $parent = $listNode->parentNode;
    while ($parent) {
        $depth++;
        $parent = $parent->parentNode;
    }
    $listWithDepth[] = [
        'depth' => $depth,
        'html' => $dom->saveHTML($listNode),
        'node' => $listNode
    ];
}

// 按深度从高到低排序
usort($listWithDepth, function($a, $b) {
    return $b['depth'] - $a['depth'];
});

// 遍历处理即可,第一个元素就是最深层级的列表
foreach ($listWithDepth as $item) {
    echo $item['html'] . PHP_EOL;
}

如果要转换为OOP结构,直接读取$item['node']的子节点、属性等信息构造对应对象即可,不需要手动处理字符串匹配。


内容的提问来源于stack exchange,提问作者Lucian Gabriel Popescu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:54:01