屏蔽字
最近在工作中做了一个聊天系统,接触到了屏蔽字,由于一开始并没有重视,导致上线后由于数据量较大出现了
卡顿的情况,多方排查后才发现原来是这个不起眼的小家伙导致的卡顿,这里就跟大家分享一下做屏蔽字的一点点小
心得。
首先实现屏蔽字我们必须需要的东西有两个,一个是我们屏蔽字的算法,另一个就是屏蔽字的表了,屏蔽字表应
该在网上都能搜到,至于是不是你想要的格式如果不是的话就只有自己处理一下了。
我这里使用的屏蔽字表格式为:
MaskWordLib ={
[1] = {
word = "傻逼",
},
}
原始暴力算法
--暴力循环
function obj:MaskBadWord(text)
for k,v in pairs(MaskWordLib) do
local textLen = string.widthSingleGbk(v.word)
if textLen <= 2 then
text = string.gsub(text,v.word,"*")
elseif textLen > 2 and textLen < 6 then
text = string.gsub(text,v.word,"**")
else
text = string.gsub(text,v.word,"***")
end
end
return text
end
这里就是简单的判断屏蔽字的长度再通过循环去测试每一个屏蔽字是否出现在字符串中,也是我们一开始使用的屏蔽字算法由于之前只是取名或者个性签名等少量的使用并没有注重算法的效率所以也就忽略了。
递归优化
local MaskWordLibGbkList = {
}--全局变量储存排序后的屏蔽字库
local OutPutText = ""--全局变量储存最后返回的字符串(因为递归时会多处修改所以需要全局变量)
--屏蔽字方法
function obj:MaskBadWord(text)
OutPutText = text --最终输出值
local localText = text --匹配函数参数
obj:FuzzyFindMaskWork(localText,1)--模糊匹配
--obj:FindMaskWork(localText,1)--全额匹配
return OutPutText
end
--全额匹配屏蔽字
function obj:FindMaskWork(localText,lastMaskWordGbk)--lastMaskWordGbk 是上一次匹配到的屏蔽字长度
local textGbk = string.widthSingleGbk(localText)--字符串长度
local textLen = string.len(localText)--字符串len长度
local Mask = "*"--替换屏蔽字的符号
for i=1,#MaskWordLibGbkList do --MaskWordLibGbkList 是通过GBK排序后的屏蔽字表
if MaskWordLibGbkList[i].Gbk >= lastMaskWordGbk