2011-09-06 44 views
6

Tôi đang cố gắng lập trình phần bổ trợ cho WoW (trong lua). Đó là bộ lọc trò chuyện dựa trên các từ cụ thể. Tôi không thể tìm ra cách để có được các mảng của những từ này được phân biệt chữ hoa chữ thường, sao cho bất kỳ kết hợp chữ hoa/chữ thường nào của từ khớp với mảng. bất kì ý kiến ​​nào đều được đánh giá cao. Cảm ơn!Mảng phân biệt chữ hoa chữ thường trong 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 

Trả lời

3
  1. Xác định keyWords nằm ngoài chức năng. Nếu không, bạn đang tái tạo bảng mỗi lần chỉ để lấy đi những khoảnh khắc sau, lãng phí thời gian trên cả quá trình tạo và GC.
  2. từ khóa Convert to patter rằng trận đấu cả trên và dưới trường hợp chữ cái.
  3. Bạn không cần dữ liệu bắt từ chuỗi, vì vậy sử dụng string.find cho tốc độ.
  4. Theo logic của bạn, nếu bạn đã có nhiều hơn một trận đấu bạn tín hiệu 'false'. Kể từ bạn chỉ cần 1 kết quả phù hợp, bạn không cần đếm chúng. Chỉ cần trả lại sai ngay khi bạn nhấn. Tiết kiệm thời gian để kiểm tra tất cả các từ còn lại . Nếu sau này bạn quyết định bạn muốn nhiều hơn một trận đấu , bạn vẫn nên kiểm tra vòng lặp đó bên trong vòng lặp và quay lại ngay sau bạn đã đạt đến số lượng mong muốn.
  5. Không sử dụng ipairs. Nó chậm hơn so với đơn giản cho vòng lặp từ 1 đến chiều dài mảng và ipairs không được chấp nhận trong Lua 5.2 anyway.

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

Kết quả là:

true 
false 
false 
false 
true 
5

Sử dụng if msg:lower():find (word:lower() , 1 , true) then

==> nó trường hợp thấp hơn cả hai đối số cho string.find: do đó trường hợp vô hồn. Ngoài ra tôi đã sử dụng string.find vì bạn có thể muốn tùy chọn 'đơn giản', không tồn tại đối với chuỗi.match.

Ngoài ra bạn có thể dễ dàng quay trở về từ đầu tiên được tìm thấy:

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

Bạn cũng có thể sắp xếp việc này với metatables, trong một cách hoàn toàn minh bạch:

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 

Bằng cách này bảng có thể được lập chỉ mục trong mọi trường hợp. Nếu bạn thêm từ mới vào nó, nó sẽ tự động giảm trường hợp chúng quá. Bạn thậm chí có thể điều chỉnh nó để cho phép phù hợp với các mẫu hoặc bất cứ điều gì bạn muốn.

Các vấn đề liên quan