String patterns: best way to ignore magic characters?

I’m currently creating a log system where users can search for specific words:

for i,record in pairs(log) do
	local labelText = string.lower(getLabelText(record))
	if string.match(labelText, searchText) then
		table.insert(newLog, record)
	end
end

My problem is though, when users enter a magic character (^$()%.[]*±?) then I receive the following error:

error: malformed pattern

The wiki states:

To search for a literal magic character, precede it by a %

So to solve this, I could technically iterate through each character in the search, check if the character is a magic character, then add a ‘%’ if so.

This seems quite inefficient though. Is there a better way to approach this?

1 Like

(I’m on my phone, in bed, in the middle of the night, so please double check everything I say😅)

If I remember correctly, string.find has an optional 4th argument to ignore all magic characters, like

string.find("3(-+3hehieudhow-$!#)_", 6, "$!#", true)

Does string.match have it too?

Edit:
woot3 has confirmed that string.match lacks that parameter, and you should therefore use string.find for this, if you want to ignore magic characters.

1 Like

For your purposes, you probably want to use string.find, it has an optional parameter that allows you to specify whether or not the pattern you use should be considered magic or not.

if labelText:find(searchText, 1, true) then
    ...

string.match does not have this optional parameter as it is specifically designed for pattern matching. You might still want to use this however, especially if you wish to allow certain magic characters to still be used. If you wish to strip out certain magic characters you can use string.gsub like so.

local sanitizedText = text:gsub("([%%%^%$%(%)%.%[%]%*%+%-%?])", "%%%1")
if labelText:match(sanitizedText) then
    ...
8 Likes

Thank you, that is brilliant. :happy3:

@boatbomber As woot3 mentioned, string.match() doesn’t work in that case, however I think I’ll use string.find() instead for the reason you mentioned!

2 Likes