2011-09-06 21 views
6

WoW (lua) için bir addon programlamaya çalışıyorum. Belirli kelimelere dayalı bir sohbet filtresi. Bu sözcüklerin dizisini büyük/küçük harf duyarsız olacak şekilde anlayamıyorum, böylece kelimenin herhangi bir üst/küçük harf bileşimi diziyle eşleşiyor. Herhangi bir fikir çok takdir edilecektir. Teşekkürler!Lua'daki büyük harf duyarsız dizi

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 

cevap

3
  1. İşlev dışındaki tuşAnahtarları tanımlayın. Aksi halde, tablonun yeniden oluşturulmasını sağlayarak, her iki oluşturma ve GC'de zaman harcıyorsunuz.
  2. Anahtar sözcükleri, hem büyük hem küçük harfler ile eşleştirin.
  3. Yakalanan verilere dizesinden gerek yoktur, bu nedenle speed için string.find işlevini kullanın.
  4. mantığınıza göre, birden fazla eşleşme varsa 'false' sinyali verirsiniz. 'dan beri sadece 1 eşleşme olması gerektiğinden, bunları saymanıza gerek yoktur. En kısa sürede vurduğunuzda yanlış döndürmeniz yeterlidir. Kalan tüm kelimelerini kontrol etmek için zaman kazandırır. Daha sonra bir eşleşmesini istediğinize karar verirseniz, yine de döngü içinde daha iyi kontrol edin ve istediğiniz sayıya ulaştığınızda en kısa sürede geri dönün.
  5. Çiftleri kullanmayın. 1'den dizi uzunluğuna kadar döngü için basit olmaktan daha yavaştır ve her iki durumda da Lua 5.2'de ipaireler kullanılmaz.

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

Sonucu geçerli:

true 
false 
false 
false 
true 
5

Kullanım if msg:lower():find (word:lower() , 1 , true) then

==> alt vakalar argümanlar her iki string.find için: dolayısıyla dava duyarsız. Ayrıca string.match için varolmayan 'düz' seçeneğini tercih edeceğiniz için string.find kullandım. Ayrıca

kolayca bulunan ilk kelime üzerinde dönebilirsiniz:

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

Ayrıca tamamen şeffaf bir şekilde, metatables ile bu sağlayabilir: Tablo dizine eklenebilir

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 

Bu şekilde her halükarda. Buna yeni kelimeler eklerseniz, otomatik olarak bunları daha küçük duruma getirir. Hatta desenlerle eşleşmeye izin vermek için istediğiniz gibi ayarlayabilirsiniz.

İlgili konular