php 8.2 中推荐用 preg_match_all() 提取简单 html 标签,如 、,需用非贪婪匹配、反向引用确保标签配对,自闭合标签单独处理,属性提取宜用命名捕获组,避免贪婪匹配与嵌套解析,复杂场景应改用 domdocument。

PHP 8.2 中匹配 HTML 标签,推荐用 preg_match_all() 配合合理正则模式,但要注意:不建议用正则解析整页 HTML(结构复杂时易出错),仅适用于简单、可控的标签提取场景,比如提取所有 <a></a>、<img> 或自闭合标签。
匹配常见单/双标签的基本写法
例如提取所有 <p></p> 和 <div> 开始与闭合标签内的文本:
<ul>
<li>使用非贪婪匹配 <code>.*? 避免跨标签误捕
[^>]* 安全匹配开始标签属性(不含 >)(.*?)\1> 确保开闭标签名一致示例代码:
$html = '<p class="intro">Hello</p><div id="main">World</div>'; $pattern = '/]*)>(.*?)/s'; preg_match_all($pattern, $html, $matches, PREG_SET_ORDER); // $matches 是每组匹配为一行的数组,$matches[0][1] 是标签名,$matches[0][3] 是内容
匹配自闭合或无内容标签(如
、)
这类标签没有闭合部分,需单独处理:
- 正则可写为:
/]*\/?>/i -
[^>]*匹配任意属性,\/?兼容<img>和<img> -
i标志确保大小写不敏感(<img>也能匹配)
注意:PHP 8.2 默认 PCRE2 引擎,支持更严格的 Unicode 属性,但普通 HTML 提取无需启用 u 修饰符,除非处理含 emoji 或中文属性值。
安全提取属性值(如 href、src、id)
若需同时抓取标签和特定属性,可在分组中嵌套命名捕获:
$pattern = '/<a>]*href=["\'](?P<url>[^"\']+)["\'][^>]*>(?P<text>.*?)/is'; preg_match_all($pattern, $html, $matches); // $matches['url'] 和 $matches['text'] 直接获得对应数组 </text></url></a>
- 命名子组
(?P<name>...)</name>让结果更直观,PHP 8.2 完全支持 -
is标志:i=忽略大小写,s=点号匹配换行(防内容跨行) - 避免用
.*匹配属性,防止因引号缺失或嵌套导致匹配失控
实际使用前的关键提醒
PHP 8.2 下仍要避开几个典型坑:
- 不要用
<.></.>—— 它会贪婪吞掉整个字符串直到最后一个> - 避免解析嵌套结构(如
<div><p>...</p></div>),正则无法可靠处理嵌套层级 - 若 HTML 来源不可信,先用
htmlspecialchars_decode()或html_entity_decode()解码,再匹配 - 对复杂需求,优先考虑 DOMDocument + XPath,比正则更健壮











