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))

这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值