在內容過濾、安全審計、數據採集等場景中,經常需要從字符串中識別、提取或移除 HTML 超鏈接。本文系統梳理三種常見需求的正則實現:判斷是否包含鏈接、提取 href 屬性值、完整解析 <a> 標簽的 URL 與錨文本。
使用正則匹配 <a> 標簽的開始與結束特徵:
<?php
$str = "ssdsf<a target='_blank' href='https://www.45it.net/' >sdf</a>sdfss";
if (preg_match("/<a\s+href=[^>]*>|<\/\s*a[^>]*>/i", $str)) {
echo "該字符串包含超鏈接";
} else {
echo "該字符串不包含超鏈接標記";
}
?>
正則解析:<a\s+href=[^>]*> 匹配帶 href 的開始標簽;<\/\s*a[^>]*> 匹配結束標簽;i 忽略大小寫。
利用零寬斷言精確定位 href= 後到 > 前的內容:
<?php
$html = "<a href='www.45it.net'>你好,點這裡看看</a><a href='www.45it.net'>你好,點這裡看看</a>";
// 將所有 href 值替換為 #
$result = preg_replace("/(?<=href=)([^>]*)(?=>)/i", "#", $html);
echo $result;
// 輸出: <a href='#'>你好...</a><a href='#'>你好...</a>
?>
正則詳解:
(?<=href=) 正向後顧斷言,定位 href= 之後
([^>]*) 匹配非 > 字符(即 URL 內容)
(?=>) 正向前顧斷言,定位 > 之前
<a> 標簽:提取 URL、錨文本、完整標簽功能函數 match_links() 返回結構化數組:
function match_links($document) {
// 正則捕獲組:1=引號 2=帶引號URL 3=無引號URL 4=錨文本 0=完整標簽
preg_match_all(
"'<\s*a\s.*?href\s*=\s*([\"'])?(?(1)(.*?)\1|([^\s>]+))[^>]*>?(.*?)</a>'isx",
$document,
$links
);
$match = ['link' => [], 'content' => [], 'all' => []];
// 合併帶引號與無引號的 URL
foreach ([$links[2], $links[3]] as $group) {
foreach ($group as $val) {
if (!empty($val)) $match['link'][] = $val;
}
}
// 錨文本
foreach ($links[4] as $val) {
if (!empty($val)) $match['content'][] = $val;
}
// 完整標簽
foreach ($links[0] as $val) {
if (!empty($val)) $match['all'][] = $val;
}
return $match;
}
// 使用示例
$html = "<a href='https://a.com'>Link A</a> text <a href=https://b.com>Link B</a>";
print_r(match_links($html));
輸出結構:
Array
(
[link] => Array ( [0] => https://a.com [1] => https://b.com )
[content] => Array ( [0] => Link A [1] => Link B )
[all] => Array ( [0] => <a href='https://a.com'>Link A</a> [1] => <a href=https://b.com>Link B</a> )
)
DOMDocument 解析器,比正則更健壯" 等),需先解碼再匹配