Invalid pattern capture with string.match

Hi, I’m working on a simple script that iterates over a table full of emoticon strings and checks if any of the emoticons are in a string of text. In each iteration, if no emoticon is found, string.match should return nil. If it isn’t nil, it should print the text “Found an emoticon”.

local text = "Hi :)";

local emoticons = {
	":)", ":-)", ":>", ":<", ":(", ":-(", ":D", "D:", ":-D", ":3", ":P", ":/", ":|",
	":o", ":O", ":c", ":C", ":')", ":'(", "c:", "C:"
}

for i,v in pairs(emoticons) do
	if (string.match(text, v) ~= nil) then
		print("Found an emoticon");
	end
end

I’m doing something wrong here, specifically on line 9 if (string.match(text, v) ~= nil) then
The error in the output reads Invalid pattern capture

I’ve tried using some other methods (I think I tried string.find too) but I always get the “Invalid pattern capture” error.

Can anyone more familiar with string manipulation help me understand why this code is wrong?

I may be totally wrong, but I think it could be because your trying to match “Hi :)” with “:)” and not just taking the “:)” from the “Hi :)”, and matching it. So instead you’d split the message your checking in this case “Hi :)” at each space with string.split(" "), then sorting through the table it gives you for the one that matches.

Using this advice, I tried splitting “text” where there is a space to turn text into a table of {"Hi", ":)"} and iterating over it, but unfortunately I’m still getting the the “Invalid pattern capture”

local text = "Hi :)";
text = string.split(text, " ");

local emoticons = {
	":)", ":-)", ":>", ":<", ":(", ":-(", ":D", "D:", ":-D", ":3", ":P", ":/", ":|",
	":o", ":O", ":c", ":C", ":')", ":'(", "c:", "C:"
}

for _, k in pairs(text) do
	for i,v in pairs(emoticons) do
		local match = string.match(k, v);
		if match ~= nil then
			print(match);
		end
	end
end

Likely due to the emojis having characters like parenthesis which is treated specially. You can use string.find instead of string.match and pass true for the plain arg so it doesn’t treat those characters specially

1 Like

i think you split all of the text

local text = "Hi :<";

local emoticons = {
	":)", ":-)", ":>", ":<", ":(", ":-(", ":D", "D:", ":-D", ":3", ":P", ":/", ":|",
	":o", ":O", ":c", ":C", ":')", ":'(", "c:", "C:"
}

local function FindEmoticon()
	for i,v in pairs(emoticons) do
		if string.find(text, v) then
			print("Found an emoticon");
		end
	end
end

pcall(function()
	FindEmoticon()
end)

I didn’t know about the plain arg but that fixed it, thanks!