Need Some Help with Tables

string.gsub can search and replace a pattern. The replacement can be a string, table or function. It returns the transformed string and the amount of matches found.
If it is a string, then each match becomes that string.

local source = "pear cheese ROCK CHEESE"

print(source:gsub("cheese", "fish"))
-- pear fish ROCK CHEESE	1
print(source:gsub("%w+", "fish")) -- %w is any word character, so %w+ is a sequence of one or more of these
-- fish fish fish fish	4

If it is a table, then the table is indexed for something to replace the match with. If the match isn’t found in the table (returns nil), then it isn’t changed.

local source = "pear cheese ROCK CHEESE"
local replacements = {
	pear = "moldy",
	CHEESE = "rock",
}

print(source:gsub("%w+", replacements))
-- moldy cheese ROCK rock	4

If it is a function, then it is called with each matching string.

local source = "pear cheese rock cheese"
local function func(match)
	return ({"bear", "ear", "gear", "dear"})[math.random(4)]
end

print(source:gsub("cheese", func))
-- pear bear rock gear	2
-- pear bear rock ear	2
-- pear ear rock ear	2
-- etc.

local filters = {
	{
		search  = {"cheese"}, -- that's a table in a table in a table
		replace = {"one", "two", "three", "four", "five", "six", "seven"},
	}, {
		search  = {"pear", "rock"},
		replace = {"red", "green", "blue"}
	}
}

local function func(match)
	match = string.lower(match)
	for _,filter in ipairs(filters) do
		if table.find(filter.search, match) then
			return filter.replace[math.random(#filter.replace)]
		end
	end
	-- returns nil implicitly
end

for i = 1,10 do
	print(source:gsub("%w+", func))
end
-- red four red six	4
-- green five red six	4
-- red one blue three	4
-- blue three green one	4
-- blue six blue five	4
-- blue two red one	4
-- red six blue two	4
-- red four red one	4
-- green six blue four	4
-- red four red five	4
-- etc.
1 Like

Thanks this is very usefull, I’m having another issue with string.find.

On this line here, I search through the text to look for the word in the whole line not just finding the exact word. But whenever I type anything at all, it filters it even though it isnt in the table.

for index, catergory in pairs(filterWords) do
	for i = 1, #catergory.word do
		local categoryUpper = catergory.word[i]:upper()
		local catergoryLower = catergory.word[i]:lower()

		if messageObject.Message:upper():find(categoryUpper) then
			local chosenMessage = math.random(1, #catergory.replace)
			local newMessage = catergory.replace[chosenMessage]
			messageObject.Message = filteredMessage
		end
	end
end

and when i print messageObject.Message:upper():find(categoryUpper) it outputs
1 0 - Server

That’s what string.find outputs. It’s supposed to do that. That’s the location it found something at.
The gotcha is that categoryUpper is "" (empty string), and string.find(anything_at_all, "") will always be 1, 0, because there is always nothingness in the start of a string and between every letter, and it has no length. Remove all ""s in your search strings.

Also mind that find, match, gsub etc. operate on patterns.
If you string.find(anything_at_all, "."), then it will return the first character, not the first dot, because . is a special match symbol that stands for “any character”. To search for a literal dot, it would have to be "%."
(the percent will not be searched for, it’s another symbol that means the next character is extra special or escaped)