如何修改preg_match正则以抓取含HTML标签的Data Contact关联邮箱
解决带HTML标签文本中提取「Data Contact:」开头邮箱的问题
这里提供两种可行的解决方案,根据需求选择:
方法一:先剥离HTML标签再匹配
这种方法最简单,先移除所有HTML标签还原为纯文本,再用优化后的匹配逻辑直接捕获邮箱:
$text = 'Some text Some text <a href="mailto:lol@gmail.eu">lol@gmail.eu</a><br /> Data Contact: <a href="mailto:atest@gmail.sbr">atest@gmail.com</a>, <a href="mailto:test@op.eu">test@op.eu</a><br /> <a href="mailto:ag@gmail.eu">ag@gmail.eu</a><br /> Some text Some text Some text'; // 移除所有HTML标签,得到纯文本内容 $cleanText = strip_tags($text); // 正则匹配「Data Contact:」后的邮箱,用括号直接捕获邮箱部分 preg_match_all("/Data Contact: +([\w.-]+@[\w.-]+)/i", $cleanText, $matches); // 遍历输出捕获到的邮箱 foreach($matches[1] as $email){ echo $email . '<br>'; }
说明
strip_tags()会自动移除所有HTML标签,保留文本内容,让邮箱地址直接出现在「Data Contact:」之后,和纯文本场景的匹配逻辑一致。- 正则里用括号
()捕获邮箱部分,直接从$matches[1]获取结果,省去了str_replace的步骤。
方法二:直接修改正则匹配带HTML的文本
如果不想剥离HTML标签,可调整正则表达式,允许「Data Contact:」和邮箱之间存在任意HTML标签或空白字符:
$text = 'Some text Some text <a href="mailto:lol@gmail.eu">lol@gmail.eu</a><br /> Data Contact: <a href="mailto:atest@gmail.sbr">atest@gmail.com</a>, <a href="mailto:test@op.eu">test@op.eu</a><br /> <a href="mailto:ag@gmail.eu">ag@gmail.eu</a><br /> Some text Some text Some text'; // 正则匹配「Data Contact:」后,跳过任意HTML标签/空白,捕获邮箱 preg_match_all('/Data Contact:(?:\s*<[^>]+>\s*|\s*)*([\w.-]+@[\w.-]+)/i', $text, $matches); foreach($matches[1] as $email){ echo $email . '<br>'; }
正则解释
Data Contact::匹配开头的标识文本(?:\s*<[^>]+>\s*|\s*)*:非捕获组,匹配任意数量的HTML标签(<[^>]+>表示任意HTML标签)或空白字符,确保跳过「Data Contact:」和邮箱之间的所有标签与空格([\w.-]+@[\w.-]+):捕获邮箱地址,\w等价于[a-zA-Z0-9_],更简洁地匹配邮箱的合法字符
该正则会自动匹配「Data Contact:」后的所有符合格式的邮箱(比如示例中的两个邮箱)。
内容的提问来源于stack exchange,提问作者user19818308
相关产品推荐
相关产品推荐

