Regex to Roblox String Pattern

Hello there. I will make this quick and short. I made the following regex that will decode morse code and split it up to be processed. Here is that regex: ((?="[^"]+"|\S+)([^\/]))+|\/

If I have the string ...-... -..-./--.-., the regex should be able to split it into the following groups:
...-...
-..-.
/
--.-.

Although this regex works, there is one problem. How exactly do I use this regex in Luau? Clearly, putting it into a string.gmatch function doesn’t do the trick, so how exactly do I use this? Thank you in advance.

Should it split the morse code by each of these characters?

It splits the morse code by white spaces and “/” (although the “/” is included in a group itself). The overall structure is like this:

image
(Image generated and taken from https://www.debuggex.com/)

1 Like

One important note is that Lua doesn’t use actual regex, but kind of a subset that it just calls pattern matching:

Source: Programming in Lua : 20.2

In terms of matching what you are requesting, it is a bit challenging with the “/” special behavior. If you only want to match groups of “-” and “.” separated by whitespace, you can easily do so by using gmatch. You can also use split, assuming the separator is always the same (or use gsub first to convert all whitespace to a space or something, and then use split).

e.g.:

local morse = "...-... -..-. --.-."

-- gmatch
for group in morse:gmatch("[%.%-]+") do
	print(group)
end

-- split
local groups = morse:split(" ")

-- split all whitespace:
local groups = morse:gsub("%s+", " "):split(" ")

-- try to handle "/" with some more logic:
local groups = {}
for k,s in morse:gmatch("([%.%-]+)(%/?)") do
	table.insert(groups, k)
	if s == "/" then
		table.insert(groups, s)
	end
end
2 Likes

Aye, this worked like a charm. I truly wish Luau had regex support, but regardless, this code does exactly what I need it to do. Thank you for the speedy response, I truly appreciate it. Have a wonderful day!

1 Like
local t = {}
local morseString = "...-... -..-./--.-."
for _, morseSubString in ipairs(string.split(morseString, " ")) do
	for i, morseWord in ipairs(string.split(morseSubString, "/")) do
		if i > 1 then table.insert(t, "/") end
		table.insert(t, morseWord)
	end
end

for _, v in ipairs(t) do
	print(v)
end

--[[
...-...
-..-.
/
--.-.
]]
1 Like

Refer to the reply above this one.

1 Like

@sleitnick code worked fine in my case (it didn’t produce any duplicates). I assume the duplicates are because he explains how each pattern works. Other than that, his code actually works and does not produce any duplicates.

If I may ask, your code worked like a charm, but what do I modify in order to get it to work in the case where the slash has spaces before it and after it (so instead of ..-../.--.-, it would be ..-.. / .--.-)? I tried using the pattern (%s%/%s?) but that didn’t seem to work. Here’s my code so far if needed:

MorseConverter.ConvertMorseToText = function(Morse)
	local MorseGroups = {}
	for k, s in Morse:gmatch("([%.%-]+)(%s?%/?%s?)") do
		print(k)
		print(s)
		table.insert(MorseGroups, k)
		if s == "/" then
			table.insert(MorseGroups, s)
		end
	end

	local FinalString = ""
	for _, MorseGroup in pairs(MorseGroups) do
		local Letter = MorseConverter.GetLetterFromMorse(MorseGroup)
		print(MorseGroup, Letter)
		if Letter == "" then continue end
		if Letter then
			FinalString = FinalString..Letter
		else
			warn("Morse \""..MorseGroup.."\" not found in MorseTable.")
		end
	end
	return FinalString
end

I assume you still want whitespaces to be hidden.

local t = {}
local morseString = "...-... -..-. / --.-."
for _, morseSubString in ipairs(string.split(morseString, " ")) do
	for i, morseWord in ipairs(string.split(morseSubString, "/")) do
		if i > 1 then table.insert(t, "/") end
		if morseWord ~= "" then table.insert(t, morseWord) end
	end
end

for _, v in ipairs(t) do
	print(v)
end

--[[
...-...
-..-.
/
--.-.
]]
1 Like