preg_replace($pattern, $replacement, $subject) 支持數組參數,可一次完成多模式替換。移除超鏈接本質是:匹配 <a ...>...</a> 結構,替換為內文或空字符串。
function removeLinksKeepText(string $html): string {
// 1. 移除 開始標籤 (保留屬性順序不固定、單雙引號)
$html = preg_replace('#]*href\s*=\s*["\'][^"\']*["\'][^>]*>#i', '', $html);
// 2. 移除 結束標籤
$html = preg_replace('##i', '', $html);
return $html;
}
// 測試
$html = '訪問 官網 或 聯繫我們。';
echo removeLinksKeepText($html);
// 輸出:訪問 官網 或 聯繫我們。
function removeLinksCompletely(string $html): string {
// 匹配整個 ... 結構 (非貪婪,跨行)
return preg_replace('#]*href\s*=\s*["\'][^"\']*["\'][^>]*>.*?#is', '', $html);
}
function replaceAllHrefs(string $html, string $newBaseUrl): string {
// 匹配 href 屬性值 (單雙引號、可能有空格)
$pattern = '/\s+href\s*=\s*(["\'])([^"\']*)\1/i';
$replacement = ' href=$1' . $newBaseUrl . '$1';
return preg_replace($pattern, $replacement, $html);
}
// 使用
$html = 'Link1 Link2';
echo replaceAllHrefs($html, 'https://newdomain.com/go?url=');
// 輸出:Link1 Link2
正則處理 HTML 存在邊界風險 (屬性含 >、註釋、CDATA、嵌套)。DOMDocument 符合標準解析:
function removeLinksDom(string $html): string {
$dom = new DOMDocument();
// 抑制 HTML5 非標準標籤警告
libxml_use_internal_errors(true);
$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
$links = $dom->getElementsByTagName('a');
// 逆序遍歷避免索引失效
for ($i = $links->length - 1; $i >= 0; $i--) {
$link = $links->item($i);
// 選項 A: 替換為文本節點 (保留文本)
$text = $dom->createTextNode($link->textContent);
$link->parentNode->replaceChild($text, $link);
// 選項 B: 完全移除 (含文本)
// $link->parentNode->removeChild($link);
}
// 輸出 (注意:saveHTML 會添加 html/body 標籤,需提取 body 內容)
$body = $dom->getElementsByTagName('body')->item(0);
if ($body) {
$result = '';
foreach ($body->childNodes as $node) {
$result .= $dom->saveHTML($node);
}
return $result;
}
return $dom->saveHTML();
}
| 方案 | 速度 | 健壯性 | 適用場景 |
|---|---|---|---|
| preg_replace 簡單正則 | 極快 | 低 (易誤匹配/漏匹配) | 受控內容、結構固定、高性能需求 |
| preg_replace 複雜正則 | 快 | 中 | 較穩定 HTML 片段 |
| DOMDocument | 較慢 (解析開銷) | 極高 (標準解析器) | 用戶生成內容 (UGC)、複雜/異常 HTML、安全敏感 |
.* 會吞噬多個標籤,必須用 .*? (非貪婪) 或 [^>]* (排除右尖括號)。href 可能不在第一個,正則需允許前綴屬性 \s+[^>]*href。href="..." 或 href='...',用 (["']) 捕獲引用 \1。s 修飾符 (DOTALL) 讓 . 匹配換行。u (UTF-8) 一致。preg_replace('#]*href\s*=\s*["\'][^"\']*["\'][^>]*>#i', '', $html) + 移除 。/\s+href\s*=\s*(["\'])([^"\']*)\1/i。htmlspecialchars() 防 XSS。