Reputation: 366
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
This function is used on a RPG server, basically I'm trying to match what the player says
e.g; if msgcontains(msg, "hi") then
msg = the message the player sent
However, it's matching anything like "yesimstupidhi", it really shouldn't match it because "hi" isn't a single word, any ideas what can I do? T_T
Upvotes: 4
Views: 8513
Reputation: 6251
Frontiers are good for dealing with boundaries of the pattern (see Lua frontier pattern match (whole word search)) and you won't have to modify the string:
return msg:match('%f[%a]'..what..'%f[%A]') ~= nil
The frontier '%f[%a]'
matches only if the previous character was not in '%a' and the next is. The frontier pattern is available since 5.1 and official since 5.2.
Upvotes: 4
Reputation: 627536
You can use a trick mentioned by Egor in his comment, namely: add some non-word characters to the input string, and then enclose the regex with non-letter %A
(or non-alphanumeric with %W
if you want to disallow digits, too).
So, use
return string.match(' '..msg..' ', '%A'..what..'%A') ~= nil
or
return string.match(' '..msg..' ', '%W'..what..'%W') ~= nil
This code:
--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
Here is a CodingGround demo
Upvotes: 1
Reputation: 2715
Just think about "what's a word". A word has specific characters in front and behind it, like whitespaces (space, tabulator, newline, carriage return, ...) or punctation (comma, semicolon, dot, line, ...). Furthermore a word can be at the text begin or end.
%s, %p, ^ and $ should interest you.
For more, see here.
Upvotes: 0