【问题标题】:Case insensitive array in LuaLua中不区分大小写的数组
【发布时间】:2011-11-10 22:39:17
【问题描述】:

我正在尝试为 WoW 编写一个插件(在 lua 中)。这是一个基于特定单词的聊天过滤器。我不知道如何使这些单词的数组不区分大小写,以便单词的任何大写/小写组合都与数组匹配。任何想法将不胜感激。谢谢!

local function wordFilter(self,event,msg)
local keyWords = {"word","test","blah","here","code","woot"}
local matchCount = 0;
    for _, word in ipairs(keyWords) do
            if (string.match(msg, word,)) then
            matchCount = matchCount + 1;
        end
    end
    if (matchCount > 1) then
            return false;
    else
        return true;
    end
end

【问题讨论】:

    标签: arrays lua case


    【解决方案1】:

    使用if msg:lower():find ( word:lower() , 1 , true ) then

    ==> 将 string.find 的两个参数都小写:因此不区分大小写。 我还使用了 string.find,因为您可能需要 'plain' 选项,而 string.match 不存在该选项。

    您还可以轻松地返回找到的第一个单词:

    for _ , keyword in ipairs(keywords) do
        if msg:lower():find( keyword:lower(), 1, true ) then return true end
    end
    return false
    

    【讨论】:

      【解决方案2】:
      1. 在函数之外定义关键字。否则你正在重新创建 每次都只是为了稍后把它扔掉,浪费时间 在创建和 GC 上。
      2. 将关键字转换为匹配的模式 大写和小写字母。
      3. 您不需要捕获的数据 来自字符串,所以使用 string.find 来提高速度。
      4. 根据您的 逻辑上,如果你有不止一场比赛,你就会发出“假”信号。自从 你只需要1场比赛,你不需要数他们。刚回来 一击就假。节省您检查所有的时间 剩下的话也是。如果以后你决定要不止一个 匹配,您最好在循环内检查它并尽快返回 您已达到所需的计数。
      5. 不要使用 ipairs。它比从 1 到数组长度的简单 for 循环要慢,而且 ipairs 在 Lua 5.2 中已被弃用。

        local keyWords = {"word","test","blah","here","code","woot"}
        local caselessKeyWordsPatterns = {}
        
        local function letter_to_pattern(c)
            return string.format("[%s%s]", string.lower(c), string.upper(c))
        end
        
        for idx = 1, #keyWords do
            caselessKeyWordsPatterns[idx] = string.gsub(keyWords[idx], "%a", letter_to_pattern)
        end
        
        local function wordFilter(self, event, msg)
            for idx = 1, #caselessKeyWordsPatterns  do
                if (string.find(msg, caselessKeyWordsPatterns[idx])) then
                    return false
                end
            end
            return true
        end
        
        local _
        print(wordFilter(_, _, 'omg wtf lol'))
        print(wordFilter(_, _, 'word man'))
        print(wordFilter(_, _, 'this is a tEsT'))
        print(wordFilter(_, _, 'BlAh bLAH Blah'))
        print(wordFilter(_, _, 'let me go'))
        

      结果是:

      true
      false
      false
      false
      true
      

      【讨论】:

        【解决方案3】:

        您也可以以完全透明的方式使用元表来安排它:

        mt={__newindex=function(t,k,v)
            if type(k)~='string' then
                error'this table only takes string keys'
            else 
                rawset(t,k:lower(),v)
            end
        end,
        __index=function(t,k)
            if type(k)~='string' then
                error'this table only takes string keys'
            else
                return rawget(t,k:lower())
            end
        end}
        
        keywords=setmetatable({},mt)
        for idx,word in pairs{"word","test","blah","here","code","woot"} do
            keywords[word]=idx;
        end
        for idx,word in ipairs{"Foo","HERE",'WooT'} do
            local res=keywords[word]
            if res then
                 print(("%s at index %d in given array matches index %d in keywords"):format(word,idx,keywords[word] or 0))
            else
                 print(word.." not found in keywords")
            end
        end
        

        这种方式可以在任何情况下索引表。如果您向其中添加新单词,它也会自动将它们小写。您甚至可以对其进行调整以允许匹配模式或任何您喜欢的内容。

        【讨论】:

          猜你喜欢
          • 2016-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-22
          • 2013-04-25
          • 2011-05-09
          • 2012-11-04
          相关资源
          最近更新 更多