首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 文章內容關鍵詞自動內鏈:三種方案從簡單到健壯演進

     編輯:PHP 相關知識

方案一:正則替換(推薦,健壯)

function yang_keyword_link($content, $keyword, $link) {
    // 1. 保護圖片屬性中的關鍵詞
    $content = preg_replace('|(<img[^>]*?)(' . $keyword . ')([^>]*?>)|U', '$1%&&&&&%$3', $content);
    // 2. 替換非標簽內的首次出現
    $regex = '/(?!((<.*?)|(<a.*?)))(' . $keyword . ')(?!(([^<>]*?)>)|([^>]*?<\/a>))/si';
    $url = '<a href="' . $link . '">' . $keyword . '</a>';
    $content = preg_replace($regex, $url, $content, 1);
    // 3. 還原圖片關鍵詞
    return str_replace('%&&&&&%', $keyword, $content);
}

優點:跳過已有鏈接、圖片 alt/title、標簽屬性,僅替換首次純文本出現。

方案二:類封裝,批量處理多關鍵詞(工程化)

class InnerLink {
    private static $spotUrlMap;
    public static function genSpotLink($basePath, $description) {
        if (empty(self::$spotUrlMap)) self::$spotUrlMap = DBViewSpot::getSpotPare(); // 從 DB 獲取映射
        if (empty($description)) return $description;
        foreach (self::$spotUrlMap as $pair) {
            $replace = "<a target='_blank' href='$basePath/{$pair[1]}.html'>{$pair[0]}</a>";
            $description = self::replaceOnceOutsideTags($description, $pair[0], $replace);
        }
        return $description;
    }
    private static function replaceOnceOutsideTags($text, $needle, $replace) {
        // 簡易實現:按 <a> 分割,僅在非鏈接段落替換首次
        $parts = explode('<a', $text);
        $replaced = false;
        foreach ($parts as &$part) {
            $sub = explode('</a>', $part);
            if (count($sub) > 1) {
                if ($sub[0][0] !== 'a' && $sub[0][0] !== 'A' && !$replaced) {
                    $sub[1] = self::strReplaceOnce($needle, $replace, $sub[1], $replaced);
                }
                $part = implode('</a>', $sub);
            } elseif (!$replaced) {
                $part = self::strReplaceOnce($needle, $replace, $part, $replaced);
            }
        }
        return implode('<a', $parts);
    }
    private static function strReplaceOnce($needle, $replace, $haystack, &$replaced) {
        $pos = strpos($haystack, $needle);
        if ($pos === false) return $haystack;
        $replaced = true;
        return substr_replace($haystack, $replace, $pos, strlen($needle));
    }
}

方案三:簡單 str_replace(教學用,有缺陷)

$keys = [
    ['網頁特效','/js_a/js.html'], ['seo','/seo/seo.html'], ['php','/phper/php.html'],
    // ...
];
$str = "今天學php好,jsp也行,css+div...";
foreach ($keys as $k) {
    if (strpos($str, $k[0]) !== false) {
        $str = str_replace($k[0], "<a href='https://example.com{$k[1]}' target='_blank'>{$k[0]}</a>", $str);
    }
}
echo $str;

缺陷:重複替換(已加鏈接的又被替換)、破壞標簽屬性、大小寫敏感、無首次限制。

核心難點與解決策略

難點方案一方案二
避開已有 <a> 標簽負向前瞻/後瞻正則按 <a>/</a> 分段處理
避開圖片屬性預佔位符保護同左
僅替換首次preg_replace limit=1標記變量控制
大小寫不敏感regex /i 修飾符strpos 大小寫敏感,需 stripos

生產環境建議

  1. 關鍵詞映射表存數據庫,後台可配置權重、啟用狀態。
  2. 內容渲染時一次性處理,緩存結果避免重複計算。
  3. 長文本分段處理,防止正則回溯超時。
  4. 提供「不加鏈」標記(如 <!-- noauto -->)供編輯控制。

總結

方案一正則法最適合單關鍵詞即時替換;方案二類封裝適合批量關鍵詞系統化管理;方案三僅供學習參考。核心原則:保護標簽結構、首次替換、大小寫不敏感、可配置化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved