博客文章

关于屏蔽某些词语,词组中间有中文、英文符号、emoji也要屏蔽

作者: andy.      时间: 2019-11-28 23:06:50

        今天晚上临时有个需求。关于屏蔽某些词语,词组中间有中文、英文符号也要屏蔽,就是比如要屏蔽一个词语:world,那么w!【or&*%&ld这种也要屏蔽。因为引擎是Cocos2d-x,语言是lua,就赶快处理了更新到线上。这里记录下思路。

        思路很简单:

        1、去掉语句中的符号得到语句sentence。

        2、在sentence中查找是否有要屏蔽的词语,并记录下这些屏蔽词所处原始语句的位置。

        3、把原始语句中,屏蔽词对应的位置给替换掉。

        贴代码,lua代码,其他语言同理:

local preChar = string.char(0)
local strChineseSymbol = "~·!@#¥%……&*()「」|:“《》?/。,‘;、】【"
local chineseSymbol = { }
local function getUtf8(str, length, startPos)
    if startPos > length then
        return
    end
    local curByte = string.byte(str, startPos)
    local byteCount = 0
    if curByte > 0 and curByte <= 143 then
        byteCount = 1
    elseif curByte >= 192 and curByte <= 223 then
        byteCount = 2
    elseif curByte >= 224 and curByte <= 239 then
        byteCount = 3
    elseif curByte >= 240 and curByte <= 247 then
        byteCount = 4
    end
    local char = nil
    if byteCount > 0 then
        char = string.sub(str, startPos, startPos + byteCount - 1)
        local a, b
        if byteCount == 1 then
            b = string.byte(char)
        elseif byteCount == 2 then
            a, b = string.unpack(char, ">H")
        elseif byteCount == 3 then
            a, b = string.unpack(preChar..char, ">I")
        elseif byteCount == 4 then
            a, b = string.unpack(char, ">I")
        end
        return b, startPos + byteCount, char
    else
        return
    end
end
local lengthOfSymbol = #strChineseSymbol
local startPos = 1
while (true) do
    local utf8, nextPos = getUtf8(strChineseSymbol, lengthOfSymbol, startPos)
    if not utf8 then
        break
    end
    startPos = nextPos
    chineseSymbol[utf8] = true
end

        上面是缓存中文标点,下面是查找替换:

function replace(str)
    local startPos = 1
    local allLength = #str
    local compareStr = ""
    local position = { }
    while (true) do
        local utf8, nextPos, char = getUtf8(str, allLength, startPos)
        if not utf8 then
            break
        end
        if chineseSymbol[utf8] or (utf8 > 0 and utf8 < 48) or (utf8 > 57 and utf8 < 65) or (utf8 > 90 and utf8 < 97) or (utf8 > 122 and utf8 < 128) or nextPos - startPos > 3 then
        else
            position[#compareStr + 1] = startPos
            compareStr = compareStr..char
            position[#compareStr] = nextPos - 1
        end
        startPos = nextPos
    end
    startPos = 1
    local subPosition = { }
    for k, v in pairs(self.words) do
        while (true) do
            local a, b = string.find(compareStr, v, startPos)
            if a and b and b >= a then
                startPos = b + 1
                table.insert(subPosition, { position[a], position[b] })
            else
                break
            end
        end
    end
    if #subPosition < 1 then
        return str
    end
    local finalStr = ""
    local index = 1
    for k, v in pairs(subPosition) do
        finalStr = finalStr..string.sub(str, startPos, v[1] - 1).."***"
        startPos = v[2] + 1
    end
    finalStr = finalStr..string.sub(str, startPos)
    return finalStr
end