DFA算法(敏感字屏蔽)

Posted 夜色魅影

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DFA算法(敏感字屏蔽)相关的知识,希望对你有一定的参考价值。

DFA算法

又称为有限状态机,是由一个树状结构实现(链表构建),每次匹配从根节点出发,遍历树查找,直到叶子节点结束。各个节点就好比各个状态一样,从上往下依次跳转。下面以敏感字查找替换为例,创建敏感词库树状结构如下:

结构图:<猪一样的队友,xxxxxxxx>
R ->	|-->a
            	|-->b
                    	|-->c
                            	|-->d
        
                                    	|-->e
                        |-->c      
        -------------------------------------------      	                
     	|-->g
     			|-->e
     					|-->f
		-------------------------------------------
		|-->猪
				|-->一
						|-->样
								|-->的
										|-->队
												|-->友
		------------------------------------------
		|-->m
				|-->n
						|-->f 

注释:主要应用于集合A字符串中是否包含B字符串这样的情形。

源码

  • lua脚本实现
--敏感词库
local warning = require('app.data.cn.StaticData_warning')

local WarnStrFunc = class('WarnStrFunc')

function WarnStrFunc:ctor()
	self:createTree()
end

--树节点创建
function WarnStrFunc:createNode(c,flag,nodes)
	local node = 
	node.c = c or nil           --字符
	node.flag = flag or 0 		--是否结束标志,0:继续,1:结尾
	node.nodes = nodes or 	--保存子节点
	return node
end

--初始化树结构
function WarnStrFunc:createTree()
	self.rootNode = self:createNode('R')  --根节点  

	for i,v in ipairs(warning) do
		local chars = self:getCharArray(v.name)
		if #chars > 0 then
			self:insertNode(self.rootNode,chars,1)
		end
	end
end

--插入节点
function WarnStrFunc:insertNode(node,cs,index)
	local n = self:findNode(node,cs[index])
	if n == nil then
		n = self:createNode(cs[index])
		table.insert(node.nodes,n)
	end

	if index == #cs then
		n.flag = 1
	end

	index = index + 1
	if index <= #cs then
		self:insertNode(n,cs,index)
	end
end

--节点中查找子节点
function WarnStrFunc:findNode(node,c)
	local nodes = node.nodes
	local rn = nil
	for i,v in ipairs(nodes) do
		if v.c == c then
			rn = v
			break
		end
	end
	return rn
end

--字符串转换为字符数组
function WarnStrFunc:getCharArray(str)
	local array = 
	local len = string.len(str)
	while str do
		local fontUTF = string.byte(str,1)
	
		if fontUTF == nil then
			break
		end

		--lua中字符占1byte,中文占3byte
		if fontUTF > 127 then 
			local tmp = string.sub(str,1,3)
			table.insert(array,tmp)
			str = string.sub(str,4,len)
		else
			local tmp = string.sub(str,1,1)
			table.insert(array,tmp)
			str = string.sub(str,2,len)
		end
	end
	return array
end

--将字符串中敏感字用*替换返回
function WarnStrFunc:warningStrGsub(inputStr)
	local chars = self:getCharArray(inputStr)
	local index = 1
	local node = self.rootNode
	local word = 
	
	while #chars >= index do
		--遇空格节点树停止本次遍历[xxxxxx -> ******]
		if chars[index] ~= ' ' then
			node = self:findNode(node,chars[index])
		end
		
		if node == nil then
			index = index - #word 
			node = self.rootNode
			word = 
		elseif node.flag == 1 then
			table.insert(word,index)
			for i,v in ipairs(word) do
				chars[v] = '*'
			end
			node = self.rootNode
			word = 
		else
			table.insert(word,index)
		end
		index = index + 1
	end

	local str = ''
	for i,v in ipairs(chars) do
		str = str .. v
	end

	return str
end

--字符串中是否含有敏感字
function WarnStrFunc:isWarningInPutStr(inputStr)
	local chars = self:getCharArray(inputStr)
	local index = 1
	local node = self.rootNode
	local word = 
	
	while #chars >= index do
		if chars[index] ~= ' ' then
			node = self:findNode(node,chars[index])
		end
		
		if node == nil then
			index = index - #word 
			node = self.rootNode
			word = 
		elseif node.flag == 1 then
			return true
		else
			table.insert(word,index)
		end
		index = index + 1
	end

	return false
end


return WarnStrFunc
  • 使用测试
local warnStrFunc          = require('app.utils.WarnStrFunc').new()
    local strTest = 'xxxxxxxxx,xxoo就是快乐的房间里GM,师傅经理收dsklfj快递放假xx啊'
    print(warnStrFunc:isWarningInPutStr(strTest))
    print(warnStrFunc:warningStrGsub(strTest))

以上是关于DFA算法(敏感字屏蔽)的主要内容,如果未能解决你的问题,请参考以下文章

Java 利用DFA算法 屏蔽敏感词

java实现敏感词过滤(DFA算法)

过滤敏感字DFA JAVA实现

基于DFA算法的敏感词过滤

Java过滤敏感词语/词汇---DFA算法

DFA敏感词过滤实现