本文目录导读:

在 Laravel 中实现敏感词过滤,使用 Trie 树(前缀树)是非常合适且推荐的做法,尤其适合需要高效检测大量敏感词的场景。
为什么推荐 Trie 树?
优势
- 时间复杂度低:O(n) 级别的匹配速度,n 为文本长度
- 内存占用合理:共享前缀节点,适合大量敏感词
- 支持最长匹配:避免误判(如“共产党”和“共产党宣言”)
常见方案对比
| 方案 | 时间复杂度 | 内存占用 | 实现复杂度 |
|---|---|---|---|
| 正则表达式 | O(n*m) | 低 | 简单 |
| Trie树 | O(n) | 中等 | 中等 |
| Aho-Corasick | O(n) | 高 | 复杂 |
| 布隆过滤器 | O(n) | 低 | 需配合 |
Laravel 中实现 Trie 树敏感词过滤
安装包(推荐)
composer require sensortree/sensitive
use SensorTree\Sensitive;
$sensitive = new Sensitive();
$sensitive->addWords(['敏感词1', '敏感词2']);
$sensitive->filter('需要过滤的文本'); // 返回替换后的文本
自定义实现
namespace App\Services;
class TrieFilter
{
private $tree = [];
public function addWord($word)
{
$node = &$this->tree;
$len = mb_strlen($word);
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($word, $i, 1);
if (!isset($node[$char])) {
$node[$char] = [];
}
$node = &$node[$char];
}
$node['end'] = true; // 标记结束
}
public function filter($text, $replace = '*')
{
$len = mb_strlen($text);
$result = '';
$positions = []; // 需要替换的字符位置
for ($i = 0; $i < $len; $i++) {
$node = $this->tree;
if (isset($node[mb_substr($text, $i, 1)])) {
$this->checkWord($text, $i, $node, $positions);
}
}
// 替换处理
for ($i = 0; $i < $len; $i++) {
$result .= isset($positions[$i]) ? $replace : mb_substr($text, $i, 1);
}
return $result;
}
private function checkWord($text, $start, $node, &$positions)
{
$len = mb_strlen($text);
for ($i = $start; $i < $len; $i++) {
$char = mb_substr($text, $i, 1);
if (!isset($node[$char])) break;
$node = $node[$char];
if (isset($node['end'])) {
// 标记要替换的字符
for ($j = $start; $j <= $i; $j++) {
$positions[$j] = true;
}
}
}
}
}
加载敏感词列表
class SensitiveService
{
protected $trie;
public function __construct()
{
$this->trie = new TrieFilter();
$words = config('sensitive.words'); // 从配置文件加载
foreach ($words as $word) {
$this->trie->addWord($word);
}
}
public function filter($text)
{
return $this->trie->filter($text);
}
}
在控制器中使用
use App\Services\SensitiveService;
class CommentController extends Controller
{
public function store(Request $request, SensitiveService $sensitive)
{
$content = $sensitive->filter($request->input('content'));
Comment::create([
'content' => $content,
'has_sensitive' => $content !== $request->input('content')
]);
return redirect()->back();
}
}
最佳实践建议
缓存 Trie 树
// 使用 Laravel 的缓存机制
Cache::rememberForever('sensitive_trie', function() {
$trie = new TrieFilter();
// 加载敏感词
return $trie;
});
分库存储敏感词
// 按等级分类
$sensitive->addWord('作弊', 1); // 1级:替换
$sensitive->addWord('赌博', 2); // 2级:直接拒绝
性能优化
- 使用
mb_*函数处理多字节字符 - 预编译 Trie 树,避免每次请求都重建
- 考虑使用 Swoole 扩展在内存中常驻
中文特殊处理
- 注意繁简体转换
- 支持拼音模糊匹配
- 处理好词语间的空格、符号
注意事项
- 内存占用:敏感词越多,Trie 树内存越大,建议控制在 10 万以内
- 并发安全:Trie 树是只读数据,不需要加锁
- 更新策略:支持热更新,但不建议频繁重建
- 误判处理:建议配合人工审核
如果对性能要求特别高(如实时聊天过滤),可以考虑使用 Aho-Corasick 算法,但实现复杂度会更高,对于大多数 Laravel 项目,Trie 树已经足够。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播