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
}]]
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:
In a format where the first item in each table is the text, and the second item in each table is the type.