// 定义命名空间
var GameClient = GameClient || {};
// DFA 实现敏感词过滤 // improve from http://blog.sina.com.cn/s/blog_53f6148101016wq1.html
GameClient.FilterWord = cc.Class.extend({
m_wordList: null, // @private
m_map: null, // @private
ctor: function (wordList) {
if (wordList == null) {
wordList = [];
}
// cc.warn("wordList: %o", wordList);
this.m_wordList = wordList;
this.m_map = this.BuildMap(wordList);
},
// 替换 str 中的敏感词为 replaceStr, step 为筛选强度, 最小为 0,最大为 5
RunFilterWord: function (str, replaceStr, step) {
if (str == undefined) {
return "";
}
if (step > 5) {
step = 5;
}
else if (step < 0) {
step = 0;
}
for (var j = 0; j < step; j++) {
var result = this.Check(this.m_map, str);
var len = result.length;
if (len == 0) {
break;
}
// 排序结果,长度长的在前面
result.sort(function (a, b) {
return b.length - a.length});
// console.log("result: " + result);
for (var i = 0; i < len; i++) {
str = str.replace(result[i], replaceStr);
}
}
return str;
},
// @private
BuildMap: function (wordList) {
var result = {};
var count = wordList.length;
// 遍历单词
for (var i = 0; i < count; ++i) {
var map = result;
var word = wordList[i];
var wordLength = word.length;
// 遍历单词的每个字母
for (var j = 0; j < wordLength; ++j) {
var ch = word.charAt(j);
var stateInfo = map[ch];
if (stateInfo == null) {
stateInfo = {};
map[ch] = stateInfo;
}
// 如果是最后一个字母,设置一个完结标识
if (j == wordLength - 1) {
stateInfo["isFinish"] = true;
}
else {
map = stateInfo;
}
}
}
return result;
},
// @private // 找出 content 中的敏感词,会返回一个包含敏感词的列表
Check: function (map, content) {
var result = [];
var count = content.length;
var stack = [];
var point = map;
// 用于标记找到关键词的标记
var isFound = false;
var foundStack = null;
for (var i = 0; i < count; ++i) {
var ch = content.charAt(i);
var item = point[ch];
// 如果没找到则复位,让主循环
if (item == null) {
if (isFound) {
isFound = false;
i = i - (stack.length - foundStack.length + 1); // 计算回退距离
result.push(foundStack.join("")); // 把单个的字母数组连成一串字符串
}
else {
i = i - stack.length; // 计算回退距离
}
stack = []; // 清空字符堆栈
point = map;
}
else if (item["isFinish"]) {
stack.push(ch);
point = item;
// 标记找到了目标词
isFound = true;
foundStack = stack.concat(); // 复制数组
}
else {
stack.push(ch);
point = item;
}
}
// 这里还要补充检查
if (isFound) {
result.push(foundStack.join("")); // 把单个的字母数组连成一串字符串
}
return result;
},
Destroy: function () {
this.m_wordList = null;
this.m_map = null;
}
});
var filterWord = new GameClient.FilterWord(["ab", "bad", "abc", "ddd", "aaa", "ccc", "bbb", "adsf", "edsdf", "ss", "fff", "aaa"]);
console.log("1: " + filterWord.RunFilterWord("asdfsdsddaadaaabbbffdassdf sdf bbb aaa a", "#", 1)); // 1: asdfsdsddaad##ffda#df sdf # # a
直接上代码