尝试检查字符串是否包含给定的单词

Trying to check if a string contains a given word

function msgcontains(msg, what)
    msg = msg:lower()

    -- Should be replaced by a more complete parser
    if type(what) == "string" and string.find(what, "|", 1, true) ~= nil then
        what = what:explode("|")
    end

    -- Check recursively if what is a table
    if type(what) == "table" then
        for _, v in ipairs(what) do
            if msgcontains(msg, v) then
                return true
            end
        end
        return false
    end

    what = string.gsub(what, "[%%%^%$%(%)%.%[%]%*%+%-%?]", function(s) return "%" .. s end)
    return string.match(msg, what) ~= nil
end

这个函数是在RPG服务器上使用的,基本上我是想匹配玩家说的

例如; if msgcontains(msg, "hi") then

msg = 玩家发送的消息

但是,它匹配 "yesimstupidhi" 之类的任何东西,它真的不应该匹配它,因为 "hi" 不是一个单词,我能做什么? T_T

想想"what's a word"。一个单词前后都有特定的字符,比如whitespaces (space, tabulator, newline, carriage return, ...) 或者标点符号(逗号,分号,点,线, ...)。此外,一个词可以在文本的开头或结尾。

%s%p^$ 你应该感兴趣。

有关更多信息,请参阅 here

你可以使用 Egor 在他的评论中提到的一个技巧,即:在输入字符串中添加一些非单词字符,然后用非字母 %A (或非字母数字与%W 如果你也想禁止数字)。

所以,使用

return string.match(' '..msg..' ', '%A'..what..'%A') ~= nil

return string.match(' '..msg..' ', '%W'..what..'%W') ~= nil

此代码:

--This will print "yes im stupid hi" since "yes" is a whole word
msg = "yes im stupid hi"
if msgcontains(msg, "yes") then
    print(msg)
end
--This will not print anything
msg = "yesim stupid hi"
if msgcontains(msg, "yes") then
    print(msg)
end

这是一个CodingGround demo

Frontiers 有利于处理模式的边界(参见 Lua frontier pattern match (whole word search)),您不必修改字符串:

return msg:match('%f[%a]'..what..'%f[%A]') ~= nil

边界 '%f[%a]' 仅当前一个字符不在 '%a' 中且下一个字符在中时才匹配。边界模式从 5.1 开始可用,从 5.2 开始正式可用。