Массив без учета регистра в Lua - PullRequest
7 голосов
/ 06 сентября 2011

Я пытаюсь запрограммировать аддон для 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

Ответы [ 3 ]

6 голосов
/ 06 сентября 2011

Используйте 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
4 голосов
/ 13 апреля 2012
  1. Определение ключевых слов вне функции. В противном случае вы воссоздаете стол каждый раз, чтобы просто проглотить моменты, потратив время как на создание, так и на GC.
  2. Конвертировать ключевые слова в скороговорку, которые соответствуют прописные и строчные буквы.
  3. Вам не нужны захваченные данные из строки, так что используйте string.find для скорости.
  4. По вашему логика, если у вас есть более одного совпадения, вы сигнализируете «ложь». поскольку вам нужно только 1 матч, вам не нужно их считать. Просто вернись ложь, как только вы нажмете. Экономит ваше время на проверку всех Остальные слова тоже. Если позже вы решите, что хотите более одного совпадать, вам все равно лучше проверить это в цикле и вернуться, как только Вы достигли желаемого количества.
  5. Не используйте ipairs. Это медленнее простого цикла for от 1 до длины массива, и в любом случае 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
2 голосов
/ 06 сентября 2011

Вы также можете организовать это с помощью метатаблиц, полностью прозрачным способом:

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

Таким образом, таблица может быть проиндексирована в любом случае. Если вы добавите в него новые слова, они автоматически будут также в нижнем регистре. Вы даже можете настроить его так, чтобы оно соответствовало шаблонам или как угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...