Validating RGB String using regex in Swift

Viewed 93

I've been trying to figure out the best way to validate a user entry which is a string with comma separated RGB values. It should only allow strings with no whitespaces and in formats such as these (1,12,123; 225,225,2; 32,42,241...).

I've never used Regex before, but i'm guessing it would be the best solution? I've been playing around on RegexPal and have gotten this string working:

(#([\da-f]{3}){1,2}(\d{1,3}%?,\s?){3}(1|0?\.\d+)\)|\d{1,3}%?(,\s?\d{1,3}%?){2})

However, not having much luck using it in Swift. I get the error "Invalid escape sequence in literal".

Would appreciate any help with using that regex in Swift, or if there's a better regex string/solution to validating the entry. Thanks!

2 Answers

Add the Swift code where you define the RegEx to your question.

The other poster likely has identified the problem. (@manzarhaq, you should really post your reply as an answer so the OP can accept it.)

The backslash is a special character in Swift strings. It tells the compiler that the character next is a special character. If you want a literal backslash, you need 2 backslashes in a row. So your regEx string might look like this:

let regExStrin = "(#([\\da-f]{3}){1,2}(\\d{1,3}%?,\\s?){3}(1|0?\\.\\d+)\\)|\\d{1,3}%?(,\\s?\\d{1,3}%?){2})"

Note that using backslashes this way is common to most languages that derive, even loosely, from C. Swift does have some C in its ancestry.

In many C-like languages, \n is a newline character, \t is a tab character, \f is a form-feed, \" is a quotation mark, and \\ is a literal backslash.

(I don't think the \f form feed character is defined in Swift. That harks back to the days of ASCII driven serial printers.)

You can use hashtag before the first double quote and after the last double quote in Swift to avoid having to manually add a backslash before any special character. Regarding the regex you are using it would allow the user to enter values above the 255 limit.

The regex below adapted from this post would limit the values from 0-255 and would allow the user enter 1 or more rgb values followed by ";" or "; "

#"^\((((([1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])),){2}(([1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]))(;|; )?){1,}\)$"#

extension StringProtocol {
    var isValidRGB: Bool { range(of: #"^\((((([1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])),){2}(([1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]))(;|; )?){1,}\)$"#,
                                 options: .regularExpression) != nil }
}

"(200,55,1)".isValidRGB // true
"(10,99,255; 0,0,10)".isValidRGB // true
"(2,2,2;)".isValidRGB // true
"(2,2,2;2)".isValidRGB // false
"(2,2,2;2,2)".isValidRGB // false
"(2,2,254;0,0,0)".isValidRGB // true
"(2,2,256;0,0,0)".isValidRGB // false
Related