【问题标题】:Trying to check if a string contains a given word尝试检查字符串是否包含给定的单词
【发布时间】:2015-07-17 19:47:00
【问题描述】:
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服务器上使用的,基本上我是在尝试匹配玩家所说的

例如; 如果 msgcontains(msg, "hi") 那么

msg = 玩家发送的消息

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

【问题讨论】:

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

标签: lua lua-patterns


【解决方案1】:

Frontiers 可以很好地处理模式的边界(参见Lua frontier pattern match (whole word search)),您不必修改字符串:

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

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

【讨论】:

  • 确实! %f 在 5.1.5 中可用!
【解决方案2】:

您可以使用 Egor 在他的评论中提到的一个技巧,即:在输入字符串中添加一些非单词字符,然后将正则表达式用非字母 %A 括起来(或非字母数字用 %W if你也想禁止数字)。

所以,使用

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

【讨论】:

    【解决方案3】:

    想想“什么是单词”。一个单词的前后都有特定的字符,如空格(空格、制表符、换行符、回车……)或标点符号(逗号、分号、点、行……)。此外,一个单词可以在文本的开头或结尾。

    %s%p^$ 应该会让您感兴趣。

    欲了解更多信息,请参阅here

    【讨论】:

      猜你喜欢
      • 2013-12-23
      • 2014-01-25
      • 1970-01-01
      • 2016-02-23
      • 2011-05-20
      • 2023-04-01
      相关资源
      最近更新 更多