要匹配 <tr...> 标签但缺少闭合标签 </tr> 的情况,有几种解决方案:

方法1:使用正则表达式容忍不完整标签

$pattern = '/<tr\b[^>]*>(?:(?!<\/tr>).)*$/is';
preg_match_all($pattern, $html, $matches);

这个正则表达式的含义:

  • <tr\b[^>]*> 匹配开始 tr 标签

  • (?:(?!<\/tr>).)* 匹配任何不包含 </tr> 的字符

  • $ 确保匹配到字符串末尾(即没有闭合标签)

方法2:使用 DOM 解析器更可靠地处理

正则表达式不是处理 HTML 的最佳工具,特别是对于不完整的标记。更好的方法是使用 PHP 的 DOM 扩展:

$dom = new DOMDocument();
libxml_use_internal_errors(true); // 禁止显示解析错误
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();

$trs = $dom->getElementsByTagName('tr');
foreach ($trs as $tr) {
    // 检查是否缺少闭合标签
    $inner = '';
    foreach ($tr->childNodes as $child) {
        $inner .= $dom->saveHTML($child);
    }
    
    if (!preg_match('/<\/tr>$/', $inner)) {
        // 处理缺少闭合标签的 tr 元素
    }
}

方法3:修复 HTML 后再处理

你也可以先尝试修复 HTML,然后再进行处理:

// 添加缺失的闭合标签
$fixedHtml = preg_replace('/<tr\b([^>]*)>(?!.*<\/tr>)/', '<tr$1></tr>', $html);

// 然后正常处理
$pattern = '/<tr\b[^>]*>.*?<\/tr>/is';
preg_match_all($pattern, $fixedHtml, $matches);

注意事项

  1. 正则表达式处理 HTML 有其局限性,对于复杂的 HTML 结构可能不可靠

  2. 如果可能,优先使用 DOM 解析器而不是正则表达式

  3. 在处理用户提供的 HTML 时要特别小心安全问题

选择哪种方法取决于你的具体需求和 HTML 的复杂程度。