lua敏感詞過濾


--過濾敏感詞(如果onlyKnowHas為true,表示只想知道是否存在敏感詞,不會返回過濾后的敏感詞,比如用戶注冊的時候,我們程序是只想知道用戶取的姓名是否包含敏感詞的(這樣也能提高效率,檢測到有一個敏感詞就直接返回),而聊天模塊是要返回過濾之后的內容的,那么onlyKnowHas可以不設,但這需要遍歷所有可能)
local function filterSensitiveWords( content , onlyKnowHas)
    if content == nil or content == '' then
        return ''
    end
  
    --獲取每一個字符
    local wordlist = {} 
    local q = 1
    for w in string.gmatch(content, ".[\128-\191]*") do   
        wordlist[q]= w
        q=q+1
    end

    --獲取字符串中從起始位置到結束位置的字符
    local function findWord( wordTable, startpos,endpos )
        local result = ''
        for i=startpos,endpos do
            result = result..wordTable[i]
        end
        return result
    end

    local length = #(string.gsub(content, "[\128-\191]", ""))  --計算字符串的字符數(而不是字節數)
    local i,j = 1,1
    local replaceList={}
    local mgc = {['敏感詞1']=true,['敏感詞2']=true,['敏感詞3']=true}
    local function check(  )
        local v = findWord(wordlist,i,j)
        local item = mgc[v]
        if item == true then
            if onlyKnowHas == true then
                return true
            end
            table.insert(replaceList,v)
            j = j+1
            i = j
        else
            j = j+1
        end
        local limit = (j-i) >= 15 and true or (j > length and true or false) 
        if limit == true then --因為一個敏感詞最多15個字,不會太長,目的提高效率
            i = i +1
            j = i 
        end
        if i <= length then
            check()
        end
    end
    check()


    if onlyKnowHas == true then
       return false
    end

   --模式串中的特殊字符   ( ) . % + - * ? [ ^ $
    --  % 用作特殊字符的轉義字符,比如%%匹配字符%     %[匹配字符[
    local specialChar = {['(']=true,[')']=true,['.']=true,['%']=true,['+']=true,['-']=true,['*']=true,['?']=true,['[']=true,['^']=true,['$']=true}
    --檢測是否有特殊字符
    local function checkSpecialChar( msg )
        local tArray = string.gmatch(msg, ".[\128-\191]*")
        local contentArray = {}
        for w in tArray do  
           table.insert(contentArray,w)
        end
        local ck = {}
        for i=1,#contentArray do
            local v = contentArray[i]
            if specialChar[v] == true then
                table.insert(ck,'%')
            end
            table.insert(ck,v)
        end
        local result=''
        for i,v in ipairs(ck) do
            result = result..v
        end
        return result
    end
    
    for i,v in ipairs(replaceList) do
     -- --這里我沒用,主要還是為了效率
        -- local count = #(string.gsub(content, "[\128-\191]", "")) --判斷多少個字符(用於計算要顯示的*個數)
        -- local star = ''
        -- for i=1,count do 
        --     star = star..'*'
        -- end
        v = checkSpecialChar(v)
        content = string.gsub( content , v , '***' )
    end
    return content
end

目前認為最優算法如下:

local function filterSensitiveWords( content , onlyKnowHas)
    if content == nil or content == '' then
        return ''
    end

    --模式串中的特殊字符   ( ) . % + - * ? [ ^ $
    --  % 用作特殊字符的轉義字符,比如%%匹配字符%     %[匹配字符[
    local specialChar = {['(']=true,[')']=true,['.']=true,['%']=true,['+']=true,['-']=true,['*']=true,['?']=true,['[']=true,['^']=true,['$']=true}
    --檢測是否有特殊字符
    local function checkSpecialChar( msg )
        local tArray = string.gmatch(msg, ".[\128-\191]*")
        local contentArray = {}
        for w in tArray do  
           table.insert(contentArray,w)
        end
        local ck = {}
        for i=1,#contentArray do
            local v = contentArray[i]
            if specialChar[v] == true then
                table.insert(ck,'%')
            end
            table.insert(ck,v)
        end
        local result=''
        for i,v in ipairs(ck) do
            result = result..v
        end
        return result
    end

    --因為找不到方案禁用虛擬鍵盤的回車鍵,所以只能代碼移除回車鍵(游戲中虛擬鍵盤不應有換行鍵的)
    --如果可以使用回車鍵的話,那么就可以發布豎着的敏感詞文字了,顯示的很明顯,沒有閱讀障礙,但明文規定不能出現很明顯的敏感詞
    --用字符隔開的敏感詞是可以接受的,因為這種用字符隔開的敏感詞情況太多,根本無法避免,所以是可以接受的
    --InputField有一個枚舉類型keyboardType來設置鍵盤的,具體沒試,也許也是一種解決方案
    local tempContent = ''
    for w in contentArray do   
        if string.byte(w) ~= 10 then --表示回車(換行)
            tempContent = tempContent..w
        end
    end
    content = tempContent
    contentArray = string.gmatch(tempContent, ".[\128-\191]*")
    
    local mgc = {''={'敏1','敏2','敏3'},,''={'黨1'}}
    
    local contentArray = string.gmatch(content, ".[\128-\191]*")
    local value,startpos,endpos,length,star
    local starChar ='*'
    --循環每一個字符
    for w in contentArray do   
        value = mgc[w] 
        if w ~= starChar and value ~= nil then
            for i,v in ipairs(value) do 
                local z = checkSpecialChar(v)
                startpos,endpos = content:find(z)
                if startpos ~= nil and endpos ~= nil then
                    if onlyKnowHas == true then
                       return true
                    end
                    length = #(string.gsub(v, "[\128-\191]", ""))
                    star = ''
                    for i=1,length  do 
                        star = star..starChar
                    end
                    content = string.gsub( content , z , star )
                    break
                end
            end
        end
    end
    if onlyKnowHas == true then
        return false
    end
    return content
end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM