Suitable Alternative to string.find("string", "input_a" or "input_b")?

Hi! I’m a little new to programming and have encountered a problem with the string.find and string.match functions. Essentially, I want to read through a given string and get the position of a pattern.

The problem that I encounter is that I’m actually wanting to look for multiple different patterns at once, and find whichever occurs first. For some reason, this operation is completely unsupported, and I cannot find a good alternative no matter where I look.

Here’s an example. Let’s say I have the string “{this{is}an}example{}”. In this instance, I might do the following, with a little psuedocode liberties;

while exampleString is engaged do
     string.find(exampleString, "{" or "}", [whatever index the last bracket was at])
end

In this example, the program would loop through and find the first { at index 1, then the second { at index 6, and then the last { at index 20. The find function will completely ignore any patterns other than the first search pattern. However, the desired outcome is simply to find either bracket that comes next. (Fun fact, when you ask the assistant about this, it will try and gaslight you into believing that it just works, and that you just need to use “|” instead of “or”.)

I’ve made a few workarounds, however they’re heavily inefficient, especially because I will be looking for 5+ patterns at once, each with varying character lengths. My only “”““successful””“” output has been to split the string into a table containing each individual character, and then run several nested if/ifelse statements on every single character and print the indexes of each pattern matched. My friend has also tried to make this work and has unfortunately been unsuccessful, and has recommended I use a dictionary of all the different patterns I’m looking for as well as a switch statement, however I don’t have any clue what I’m doing. Does anyone have any suggestions on making a suitable workaround for this problem? Thanks!

It sounds like you’re looking for a class set:

local function allCurlyBracketPositions(input: string)
	local pattern = "[{}]"
	
	local lastPosition = 0
	local nextPosition = nil

	while true do
		nextPosition = string.find(input, pattern, lastPosition + 1)
		if not nextPosition then
			return
		end
			
		print(nextPosition)
			
		lastPosition = nextPosition
	end
end


allCurlyBracketPositions("{this{is}an}example{}")
--[[
1
6
9
12
20
21
]]

You may be interested in string.gmatch or string.gsub’s callback overload. Do note that class sets can only support single characters

2 Likes

Oh, cool! This seems to work great. However, how would I got about adding more functionality to it? My main problem is going to be that some of my inputs are more than a single character.

Here, let’s say I’m looking for the patterns “time”, “space”, and “reality”. Then let’s say I have the following string: “Space-time is a fundamental concept of space and the universe that needs to be fully understood in order to manipulate reality.

How would I set that up in this program? My initial thought is to try and use multiple string.gmatch functions to find all of those patterns, and then try to order what all was found. (For instance, the order of the patterns in that string would ideally be space, time, space, reality.) However, for some reason this strikes me as heavily inefficient. Would you have any suggestions on how to make this function, or are my initial intuitions correct?

Additionally, I’m going to want to execute some function dependent on what was matched, however I believe I have an idea of how to do that. Essentially, I would set up an if/ifelse block (or a switch statement if I’m not lazy) and simply detect which specific pattern was found, and then start a function based off what pattern was found.