Lua 中不区分大小写的数组

发布于 2024-12-03 14:06:19 字数 504 浏览 1 评论 0原文

我正在尝试为 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

I'm trying to program an addon for WoW (in lua). It's a chat filter based on specific words. I can't figure out how to get the array of these words to be case insensitive, so that any upper/lower case combination of the word matches the array. Any ideas would be greatly appreciated. Thanks!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

百变从容 2024-12-10 14:06:19

使用 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

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

==> it lower cases both of the arguments to string.find: hence case insensitivity.
Also I used string.find because you probably want the 'plain' option, which doesn't exist for string.match.

Also you can easily return on the first word found:

for _ , keyword in ipairs(keywords) do
    if msg:lower():find( keyword:lower(), 1, true ) then return true end
end
return false
方觉久 2024-12-10 14:06:19
  1. 在函数之外定义关键字。否则你就是在重新创造
    每次都把它扔掉,浪费时间
    关于创建和 GC。
  2. 将关键字转换为匹配的模式
    大写和小写字母。
  3. 您不需要捕获的数据
    来自字符串,因此使用 string.find 来提高速度。
  4. 根据你的
    逻辑上,如果你有多个匹配项,你就会发出“假”信号。自从
    你只需要 1 场比赛,你不需要计算它们。刚回来
    一旦你击中它,就会出现错误。节省您检查所有内容的时间
    余言也。如果稍后您决定想要多个
    匹配,你最好在循环中检查它并尽快返回
    您已达到所需的计数。
  5. 不要使用 ipair。它比从 1 到数组长度的简单 for 循环要慢,而且 ipairs 在 Lua 5.2 中已被弃用。

    <块引用>

    本地关键字 = {"word","test","blah","here","code","woot"}
    本地 caselessKeyWordsPatterns = {}
    
    局部函数 letter_to_pattern(c)
        return string.format("[%s%s]", string.lower(c), string.upper(c))
    结尾
    
    对于 idx = 1,#keyWords 执行
        caselessKeyWordsPatterns[idx] = string.gsub(keyWords[idx], "%a", letter_to_pattern)
    结尾
    
    本地函数 wordFilter(self, event, msg)
        对于 idx = 1,#caselessKeyWordsPatterns 执行
            if (string.find(msg, caselessKeyWordsPatterns[idx])) then
                返回错误
            结尾
        结尾
        返回真
    结尾
    
    当地的 _
    打印(wordFilter(_,_,'天哪,哈哈'))
    print(wordFilter(_, _, '词人'))
    print(wordFilter(_, _, '这是一个 tEsT'))
    print(wordFilter(_, _, '废话废话'))
    print(wordFilter(_, _, '让我走'))
    

结果是:

true
false
false
false
true
  1. Define keyWords outside of function. Otherwise you're recreating
    table every time just to thorw it away moments latter, wasting time
    on both creation and GC.
  2. Convert keyWords to patter that match
    both upper and lower case letters.
  3. You don't need captured data
    from string, so use string.find for speed.
  4. According to your
    logic, if you've got more than one match you signal 'false'. Since
    you need only 1 match, you don't need to count them. Just return
    false as soon as you hit it. Saves you time for checking all
    remaining words too. If later you decide you want more than one
    match, you still better check it inside loop and return as soon as
    you've reached desired count.
  5. Don't use ipairs. It's slower than simple for loop from 1 to array length and ipairs is deprecated in 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'))
    

Result is:

true
false
false
false
true
涙—继续流 2024-12-10 14:06:19

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

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

这样在任何情况下都可以对表进行索引。如果您向其中添加新单词,它也会自动将其小写。您甚至可以调整它以允许与图案或您想要的任何内容匹配。

You can also arrange this with metatables, in an entirely transparent way:

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

This way the table can be indexed in whatever case. If you add new words to it, it will automatically lower-case them too. You can even adjust it to allow matching with patterns or whatever you'd like.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文