要匹配 <tr...>
标签但缺少闭合标签 </tr>
的情况,有几种解决方案:
$pattern = '/<tr\b[^>]*>(?:(?!<\/tr>).)*$/is';
preg_match_all($pattern, $html, $matches);
这个正则表达式的含义:
<tr\b[^>]*>
匹配开始 tr 标签
(?:(?!<\/tr>).)*
匹配任何不包含 </tr>
的字符
$
确保匹配到字符串末尾(即没有闭合标签)
正则表达式不是处理 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 元素
}
}
你也可以先尝试修复 HTML,然后再进行处理:
// 添加缺失的闭合标签
$fixedHtml = preg_replace('/<tr\b([^>]*)>(?!.*<\/tr>)/', '<tr$1></tr>', $html);
// 然后正常处理
$pattern = '/<tr\b[^>]*>.*?<\/tr>/is';
preg_match_all($pattern, $fixedHtml, $matches);
正则表达式处理 HTML 有其局限性,对于复杂的 HTML 结构可能不可靠
如果可能,优先使用 DOM 解析器而不是正则表达式
在处理用户提供的 HTML 时要特别小心安全问题
选择哪种方法取决于你的具体需求和 HTML 的复杂程度。