php实现敏感词过滤
使用正则表达式匹配敏感词
将敏感词存储为数组,通过正则表达式构建匹配模式。使用preg_replace函数替换敏感词为指定字符(如*)。
$sensitiveWords = ['敏感词1', '敏感词2', '测试'];
$pattern = '/(' . implode('|', array_map('preg_quote', $sensitiveWords)) . ')/i';
$text = "这是一段包含敏感词1和测试的文字";
$filteredText = preg_replace($pattern, '*', $text);
使用Trie树提高检测效率
对于大量敏感词场景,构建Trie树数据结构实现高效匹配。需自定义Trie类实现插入和搜索方法,遍历文本时进行多模式串匹配。

class TrieNode {
public $children = [];
public $isEnd = false;
}
class SensitiveWordFilter {
private $root;
public function __construct() {
$this->root = new TrieNode();
}
public function addWord($word) {
$node = $this->root;
for ($i = 0; $i < mb_strlen($word); $i++) {
$char = mb_substr($word, $i, 1);
if (!isset($node->children[$char])) {
$node->children[$char] = new TrieNode();
}
$node = $node->children[$char];
}
$node->isEnd = true;
}
public function filter($text) {
$result = [];
$length = mb_strlen($text);
for ($i = 0; $i < $length; $i++) {
$node = $this->root;
$j = $i;
while ($j < $length) {
$char = mb_substr($text, $j, 1);
if (!isset($node->children[$char])) break;
$node = $node->children[$char];
if ($node->isEnd) {
$result[] = mb_substr($text, $i, $j - $i + 1);
$i = $j;
break;
}
$j++;
}
}
return str_replace($result, '*', $text);
}
}
结合数据库存储敏感词
将敏感词存储在数据库表中,定期更新缓存。使用文件缓存或内存缓存(如Redis)存储加载的敏感词列表,避免频繁查询数据库。

// 从数据库加载敏感词示例
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$stmt = $pdo->query("SELECT word FROM sensitive_words");
$words = $stmt->fetchAll(PDO::FETCH_COLUMN);
// 使用APCu缓存
if (!apcu_exists('sensitive_words')) {
apcu_store('sensitive_words', $words, 3600);
}
$cachedWords = apcu_fetch('sensitive_words');
处理中英文混合场景
针对多语言场景,使用mb_系列函数处理多字节字符。对英文单词进行边界检测避免误匹配(如"ass"不应匹配"class"中的"ass")。
function filterMixedText($text, $words) {
$pattern = '/(?<!\w)(' . implode('|', array_map('preg_quote', $words)) . ')(?!\w)/iu';
return preg_replace($pattern, '[censored]', $text);
}
实现分级过滤机制
根据敏感程度将词汇分为不同级别,采用不同处理策略。可在替换时记录日志供后续分析,对高风险词汇直接阻断内容提交。
$level1 = ['暴力词汇'];
$level2 = ['轻度敏感词'];
$text = "包含暴力词汇的内容";
if (preg_match('/'.implode('|', $level1).'/', $text)) {
header('HTTP/1.1 403 Forbidden');
exit('内容包含禁止使用的词汇');
} else {
$filtered = preg_replace('/'.implode('|', $level2).'/', '', $text);
}






