?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  
------------------------------调用示例-------------------------
 
/*
 * 替换敏感词为指定字符
 * */
require_once __DIR__ . '/TrieTree.php';
//要检测的文字
$txt = "测试敏感词过滤,卧槽";
 
//实例化类 获取处理完毕的字符串
$txt_new = (new TrieTree($txt))->endString;
 
echo $txt_new;
 
---------------------------------- 过滤算法类 ---------------------------------------
     
class TrieTree
{
    /**
     * 替换码
     * @var string
     */
    private $replaceCode = '萌';
 
    /**
     * 敏感词库集合
     * @var array
     */
    private $trieTreeMap = [];
 
    /*
     * 要开始过滤的字符串
     * @var string
     * */
    private $beginString;
 
    /*
     * 要开始过滤的字符串
     * @var string
     * */
    public $endString;
 
    /**
     * 干扰因子集合
     * @var array
     */
    private $disturbList = ['&''*''#''?''!''¥''('')'':''‘''’''“''”''《''》'',''…''。''、''nbsp''】''【''~'];
 
    public function __construct($txt = '')
    {
        $this->beginString = $txt;
        $this->addWords();
        //替换过后的文字显示
        $this->endString = $this->filter();
    }
 
    /*
     * 添加铭感词
     * 获取敏感词列表(数组)
     * 敏感词的存储方法:
     * 1:存储在txt文件中(一般的方法)
     * 2:存储在缓存(比较好的方法)
     * 我是存储在memcachd中。
     * */
    public function addWords()
    {
        //加载
        $wordsList = require_once __DIR__ . '/sensitiveWord.php';
 
        foreach ($wordsList as $words) {
            $nowWords = &$this->trieTreeMap;
            $len = mb_strlen($words);
            for ($i = 0; $i < $len; $i++) {
                $word = mb_substr($words, $i, 1);
                if (!isset($nowWords[$word])) {
                    $nowWords[$word] = false;
                }
                $nowWords = &$nowWords[$word];
                // var_dump($nowWords);
                //print_r($this->trieTreeMap);
            }
        }
    }
 
    /**
     * 查找对应敏感词
     * @return array
     */
    protected function search($hasReplace = false, &$replaceCodeList = array())
    {
        $wordsList = array();
        $txtLength = mb_strlen($this->beginString);
        for ($i = 0; $i < $txtLength; $i++) {
            $wordLength = $this->checkWord($i, $txtLength);
            if ($wordLength > 0) {
                $words = mb_substr($this->beginString, $i, $wordLength);
                $wordsList[] = $words;
                $hasReplace && $replaceCodeList[] = str_repeat($this->replaceCode, mb_strlen($words));
                $i += $wordLength - 1;
            }
        }
        return $wordsList;
    }
 
    /**
     * 过滤敏感词
     * @return mixed
     */
    public function filter()
    {
        $replaceCodeList = array();
        $wordsList = $this->search(true, $replaceCodeList);
        if (empty($wordsList)) {
            return $this->beginString;
        }
        return str_replace($wordsList, $replaceCodeList, $this->beginString);
    }
 
    /**
     * 敏感词检测
     * @param $beginIndex
     * @param $length
     * @return int
     */
    private function checkWord($beginIndex, $length)
    {
        $flag = false;
        $wordLength = 0;
        $trieTree = &$this->trieTreeMap;
        for ($i = $beginIndex; $i < $length; $i++) {
            $word = mb_substr($this->beginString, $i, 1);
            if ($this->checkDisturb($word)) {
                $wordLength++;
                continue;
            }
            if (!isset($trieTree[$word])) {
                break;
            }
            $wordLength++;
            if ($trieTree[$word] !== false) {
                $trieTree = &$trieTree[$word];
            else {
                $flag = true;
            }
        }
        $flag || $wordLength = 0;
        return $wordLength;
    }
 
    /**
     * 干扰因子检测
     * @param $word
     * @return bool
     */
    private function checkDisturb($word)
    {
        return in_array($word, $this->disturbList);
    }
}
 
 
/**
 * sensitiveWord.php
 *
 * 铭感词文件
 *
 * 2017 Copyright (c) https://note.jsx6.com
 *
 * 修改历史
 * ----------------------------------------
 * 2017/10/18, 作者: 降省心(QQ:1348550820), 操作:创建
 **/
 
  

 

---------------------------------------------------------------------------------------------
唯有志存高远,方能风行天下。

道之所存,虽千万人吾往矣! 情之所钟,虽千万里吾念矣~

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。