How to detect if a string is an RGB colour value

Heyyo!

I need some help figuring out how to detect if a certain string is a colour value…

For instance

local Colour_1 = "255, 85, 85"
local Colour_2 = "10, ab"

How would I make it print its respective thing?
Colour_1 → “Yes”
Colour_2 → “No”

Check if one has any letters inside it: (you need to remove komma’s and spaces first)

function CheckStringIfRgb(input)
   local str = string.gsub(input, ",", "")
   local str = string.gsub(str , " ", "")
   if tonumber(str) ~= nil then
       return true
   else
       return false
   end
end

I’m not a string manipulation expert, but this allows you to ignore invalid colors (any component below 0 or over 255 [or 1]):

local Integer = "255, 230, 200"
local Float = "0.2, 0.5, 0.8"
local Integer_Erroneous = "256, 255, 254"
local Float_Erroneous = "1.1, 1.4, 1"

local function Is_Color_Compatible(S : string, Use_RGB : boolean?)
	local Splits = S:split(",")
	
	local R, G, B = tonumber(Splits[1]), tonumber(Splits[2]), tonumber(Splits[3])
	
	assert(typeof(R) == "number", "R is not a number.")
	assert(typeof(G) == "number", "G is not a number.")
	assert(typeof(B) == "number", "B is not a number.")
	
	local Out_Of_Bounds = {}
	local Invalid = false
	
	for K, C_Comp in pairs({R = R, G = G, B = B}) do
		if Use_RGB then
			if not (C_Comp <= 255 and C_Comp >= 0) then
				Out_Of_Bounds[K] = C_Comp
				Invalid = true
			end
		else
			if not (C_Comp <= 1 and C_Comp >= 0) then
				Out_Of_Bounds[K] = C_Comp
				Invalid = true
			end
		end
	end
	
	if Invalid then
		warn("The following color components are invalid:", Out_Of_Bounds)
		
		return false
	end
	
	return true
end

-- RGB int
print(Is_Color_Compatible(Integer, true))
print(Is_Color_Compatible(Integer_Erroneous, true))

-- RGB float
print(Is_Color_Compatible(Float))
print(Is_Color_Compatible(Float_Erroneous))

Updated with decimal numbers (e.g Color3.new(1, 0.5, 0.2))

Most optimal way is this:

print(string.match("255, 255, 255", "^[0-255]+, [0-255]+, [0-255]+")) -- True (returns the match if true else nil)

This ensures that the values are present and they are in the range of 0-255.

1 Like

How would I use this to determine a value such as “30, 10, 2”?

You can just do

print(string.match("YOUR_VALUE", "^[0-255]+, [0-255]+, [0-255]+")) -- True (returns the match if true else nil)

And just check whether the return value isn’t nil, (if its nil, it means it doesnt match).

I guess I should say I am not understanding how it functions nor how to use it properly… When I put my value it just returns nil and it meets the requirements of 0 - 255

Could you show me your current code?

image

Apologize for my previous post, I mistook the title of the post.
If the strings you are feeding into the function are formatted like that, you can use:

function isRGBValue(colorstring)
    colorstring = string.gsub(colorstring," ","");
    local colortable = string.split(colortable,",");
    if #colortable ~= 3 then
        return false
    else
        for _,v in ipairs(colortable) do
            if tonumber(v) ~= nil or tonumber(v) < 0 or tonumber(v) > 255 then
                return false
            end
        end
    end
    return true
end
1 Like

I’ll test this right now! TY… |Extra Characters|

Thank you man! Works wonderfully!

local function stringToColor3(s : string) : (string) -> (Color3)
	local t : {} = string.split(s, ", ")
	for i, v in ipairs(t) do
		t[i] = math.clamp(v, 0, 255)
	end
	return Color3.new(table.unpack(t))
end

local c : Color3 = stringToColor3("255, 85, 85")
print(c.R, c.G, c.B) --255, 85, 85
local c : Color3 = stringToColor3("500, 500, 500")
print(c.R, c.G, c.B) --255, 255, 255

The original poster-sama asked to detect if the RGB color string is valid, not a conversion function that fixes range using clamping.

if #t ~= 3 then return end --Before the loop.
if not tonumber(v) then return end --Inside of the loop.

Then add these two lines. It may as well return a ‘Color3’ value since one is likely going to be constructed anyway.

Added a few comments to highlight some issues.

function isRGBValue(colorstring) --Should be defined locally.
	colorstring = string.gsub(colorstring," ",""); --Will error if 'colorstring' is not a string.
	local colortable = string.split(colortable,","); --Would also error if 'colorstring' is not a string.
	if #colortable ~= 3 then
		return false
	else
		for _,v in ipairs(colortable) do
			if tonumber(v) < 0 or tonumber(v) > 255 then --Will error if 'tonumber' returns 'nil' (attempt to compare nil and number).
				return false
			end
		end
	end
	return true
end

the second and third will probably never apply since, quoting a tf2 developer, No one will ever try to pass in bad data? Right?, but in all seriousness, they will probably be using this with the text of a textbox or from .Chatted, which in themselfves, give strings!

they will probably be using this with the text of a textbox or from .Chatted

‘probably’ being the operative word (speculative). What about the third issue? It should be noted that calling tonumber on the same value twice is redundant.

function isRGBValue(colorstring) --Should be defined locally.
	colorstring = string.gsub(colorstring," ","");
	local colortable = string.split(colorstring,",");
	if #colortable ~= 3 then
		return false
	else
		for _,v in pairs(colortable) do
			if tonumber(v) == nil or tonumber(v) < 0 or tonumber(v) > 255 then
				return false
			end
		end
	end
	return true
end

This is with all bugs fixed lol
I’m sorry for partially necro bumping :stuck_out_tongue:

Hey, what is the RGB range for Roblox?
0-255 or 0-100?