Is there an "or" pattern in string manipulation?

Hello, im making a command console and im trying to find a way to get words and quotes as arguments.

Im using gmatch to get the arguments, but im only able to either get words or quotes and not both.

local QuotePattern = '".+"'
local WordPattern = "[^%s]+"

local Arguments = {}
for Word in gmatch(Message, WordPattern) do
	insert(Arguments, Word)
end

Is there a way to combine the patterns so the gmatch function gives me either words or quotes in a segregated fashion? I really don’t want to make complicated loops.

For example this should be the result:

local Message = 'ban NexusKorthos "You are cheating noob" 5'
local Arguments = {
	"ban", --word
	"NexusKorthos", --word
	"You are cheating noob", --quote
	"5" --word
}]]
1 Like

Unfortunately, there is no or pattern (in the way you defined it) in Regular Expression.

Loops may be required in order to achieve the solution. The solution will be similar to @boatbomber’s Lexer for Lua.

local Quote = '".-"' -- "aaaa" "bbb" might return "aaaa" "bbb" since the + would try to get the most text. We're using - to try to get the least text.
local Quote_Incomplete = '".+' -- In the event that the command doesn't have their quotes closed correctly
local Word = "[^%s]+"
local Whitespace = "%s+"

local Matches = {
	-- Formatted as: {text, identifier}
	{Quote, "quote"},
	{Quote_Incomplete, "quote_incomplete"},

	{Word, "word"},
	{Whitespace, "whitespace"}
}

local function SeparateCommand(Command)
	local Tokens = {}
	local Index = 1
	local Length = #Command
	while Index <= Length do
		for _, Match in ipairs(Matches) do -- Loop through the table in the specific order it has been ordered as. Some things might break if they weren't ordered correctly.
			local IndexStart, IndexEnd = string.find(Command, "^" .. Match[1], Index)
			if not IndexEnd then continue end -- Indicates that the string didn't get a match. If so, continue to the next one.
			Index = IndexEnd + 1
			if Match[2] == "whitespace" then continue end -- Don't include whitespaces
			table.insert(Tokens, {string.sub(Command, IndexStart, IndexEnd), Match[2]})
		end
	end
	return Tokens
end

Using the SeparateCommand function on the string ban NexusKorthos "You are cheating noob" 5, you get this table:

image

In a format where the first item in each table is the text, and the second item in each table is the type.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.