在代碼片段或文本中,將預定義關鍵詞(如 PHP 保留字)包裹 <span class="kw"> 實現高亮,要求全詞匹配、不破壞 HTML 結構、忽略註釋內關鍵詞。
<?php
function codeWords($code) {
$keywords = [
'as','break','case','class','continue','default','do','elif','else','elseif',
'for','foreach','function','if','new','null','return','self','switch',
'this','to','typeof','until','var','void','while','with'
];
// 1. 構造全詞匹配正則:排除 // 註釋後的內容
// (?://.*)? 匹配可選的行內註釋,\K 重置匹配起點(PHP 5.2.4+)
// 兼容舊版本用捕獲組替代 \K
array_walk($keywords, function(&$v) {
$v = "/^((?:(?!\\/\\/).)*)\\b$v\\b/";
});
// 2. 構造替換模板
$replacements = array_map(function($kw) {
return "$1$kw";
}, $keywords);
// 3. 執行替換
return preg_replace($keywords, $replacements, $code);
}
// 使用
$source = '';
echo codeWords($source);
?>
| 模式 | 含義 |
|---|---|
^((?:(?!//).)*) | 行首開始,匹配任意非 // 開頭的字符(負向前瞻),捕獲到組 1 |
\b | 單詞邊界,確保全詞匹配(不匹配 className 中的 class) |
$kw | 關鍵詞本身 |
\b | 結束邊界 |
替換 $1 | 保留註釋前內容(組1),關鍵詞包裹 span |
function highlightKeywords($text, array $keywords, $tag='span', $class='keyword', $encoding='UTF-8') {
// 1. 轉義關鍵詞用於正則
$escaped = array_map(function($kw) { return preg_quote($kw, '/'); }, $keywords);
// 2. 構造大正則:單詞邊界 + 非註釋區域(簡化版,實際需語言感知解析器)
$pattern = '/\b(' . implode('|', $escaped) . ')\b/';
// 3. 替換
return preg_replace_callback($pattern, function($m) use ($tag, $class) {
return "<$tag class=\"$class\">{$m[0]}$tag>";
}, $text);
}
// 使用
$phpKeywords = ['if','else','while','for','function','class','public','private','protected'];
echo highlightKeywords($code, $phpKeywords, 'span', 'kw-php');
preg_replace 可能觸發 pcre.backtrack_limit,需分塊處理htmlspecialchars,防 XSS