Validating RGB String using regex in Swift - ios

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!

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

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.)

Related

How to remove ANSI codes from a string?

I am working on string manipulation using LUA and having trouble with the following problem.
Using this as an example of the original data I am given -
"[0;1;36m(Web): You say, "Text here."[0;37m"
I want to keep the string intact except for removing the ANSI codes.
I have been pointed toward using gsub with the LUA pattern matching but I cannot seem to get the pattern correct. I am also unsure how to reference exactly the escape character sent.
text:gsub("[\27\[([\d\;]+)m]", "")
or
text:gsub("%x%[[%d+;+]m", "")
If successful, all I want to be left with, using the above example, would be:
(Web): You say, "Text here."
Your string example is missing the escape character, ASCII 27.
Here's one way:
s = '\x1b[0;1;36m(Web): You say, "Text here."\x1b[0;37m'
s = s:gsub('\x1b%[%d+;%d+;%d+;%d+;%d+m','')
:gsub('\x1b%[%d+;%d+;%d+;%d+m','')
:gsub('\x1b%[%d+;%d+;%d+m','')
:gsub('\x1b%[%d+;%d+m','')
:gsub('\x1b%[%d+m','')
print(s)

Invalid escape sequence in literal with regex [duplicate]

This question already has an answer here:
Ignore escaped double quote characters swift
(1 answer)
Closed 6 years ago.
I define a string with:
static let Regex_studio_tel = "^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$"
But there comes an issue:
Invalid escape sequence in literal
The picture I token:
Edit -1
My requirement is match special plane numbers use Regex, such as:
My company have a special plane number:
028-65636688 or 85317778-8007
// aaa-bbbbbbbb-ccc we know the aaa is the prefix, and it means City Dialing Code, and bbbbbbbb is the main tel number, cccc is the landline telephone's extension number,
such as my company's landline telephone is 028-65636688, maybe our company have 10 extension number: 028-65636688-8007 ,028-65636688-8006,028-65636688-8005 and so on.
Of course, it maybe have a ext-number at the end.
028-65636688-2559
Two character sequence \ - is not a valid escape sequence in Swift String. When you need to pass \ - to NSRegularExpression as pattern, you need to write \\- in Swift String literal.
So, your line should be something like this:
static let Regex_studio_tel = "^(0[0-9]{2,3}\\-)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?$"
ADDITION
As Rob commented, minus sign is not a special character in regex when appearing outside of [ ], so you can write it as:
static let Regex_studio_tel = "^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$"
I'm guessing that your intent was to escape the - characters. But that's not necessary (and is incorrect). If your intent was to match just dashes, you should remove those backslashes entirely:
let pattern = "^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$"
Unrelated, but I'm suspicious of that + character. Did you really mean that you wanted to match one or more occurrences of [2-9][0-9]{6,7}? Or did you want to match exactly one occurrence?

SWIFT string with special characters without escape

How to print all special characters without inserting escape sign before every of them? I have very large textiles with many special characters and I'm looking for something like # in c# which prints string literally as it is
What you're referring to, is called a verbatim string literal in C# and that concept does not translate exactly to Swift.
However, with the introduction of multiline string Literals in Swift 4, you can get close.
let multilineString = """
Here you can use \ and newline characters.
Also single " or double "" are allowed.
"""
For reference, find the grammar of a Swift String literal here.

Removing single backslash from string

I am getting a string for a place name back from an API: "Moe\'s Restaurant & Brewhouse". I want to just have it be "Moe's Restaurant & Brewhouse" but I can't get it to properly format without the \.
I've seen the other posts on this topic, I've tried placeName?.stringByReplacingOccurrencesOfString("\\", withString: "") and placeName?.stringByReplacingOccurrencesOfString("\'", withString: "'"). I just can't get anything to work. Any ideas so I can get the string how I want it without the \? Any help is greatly appreciated, thanks!!
You report that the API is returning "Moe\'s Restaurant & Brewhouse". More than likely you are looking at a Swift dictionary or something like that and it is showing you the string literal representation of that string. But depending upon how you're printing that, the string most likely does not contain any backslash.
Consider the following:
let string = "Moe's"
let dictionary = ["name": string]
print(dictionary)
That will print:
["name": "Moe\'s"]
It is just showing the "string literal" representation. As the documentation says:
String literals can include the following special characters:
The escaped special characters \0 (null character), \\ (backslash), \t (horizontal tab), \n (line feed), \r (carriage return), \" (double quote) and \' (single quote)
An arbitrary Unicode scalar, written as \u{n}, where n is a 1–8 digit hexadecimal number with a value equal to a valid Unicode code point
But, note, that backslash before the ' in Moe\'s is not part of the string, but rather just an artifact of printing a string literal with an escapable character in it.
If you do:
let string2 = dictionary["name"]!
print(string2)
It will show you that there is actually no backslash there:
Moe's
Likewise, if you check the number of characters:
print(dictionary["name"]!.characters.count)
It will correctly report that there are only five characters, not six.
(For what it's worth, I think Apple has made this far more confusing than is necessary because it sometimes prints strings as if they were string literals with backslashes, and other times as the true underlying string. And to add to the confusion, the single quote character can be escaped in a string literal, but doesn't have to be.)
Note, if your string really did have a backslash in it, you are correct that this is the correct way to remove it:
someString.stringByReplacingOccurrencesOfString("\\", withString: "")
But in this case, I suspect that the backslash that you are seeing is an artifact of how you're displaying it rather than an actual backslash in the underlying string.

string format checking (with partly random string)

I would like to use regular expression to check if my string have the format like following:
mc_834faisd88979asdfas8897asff8790ds_oa_ids
mc_834fappsd58979asdfas8897asdf879ds_oa_ids
mc_834faispd8fs9asaas4897asdsaf879ds_oa_ids
mc_834faisd8dfa979asdfaspo97asf879ds_dv_ids
mc_834faisd111979asdfas88mp7asf879ds_dv_ids
mc_834fais00979asdfas8897asf87ggg9ds_dv_ids
The format is like mc_<random string>_oa_ids or mc_<random string>_dv_ids . How can I check if my string is in either of these two formats? And please explain the regular expression. thank you.
That's a string start with mc_, while end with _oa_ids or dv_ids, and have some random string in the middle.
P.S. the random string consists of alpha-beta letters and numbers.
What I tried(I have no clue how to check the random string):
/^mc_834faisd88979asdfas8897asff8790ds$_os_ids/
Try this.
^mc_[0-9a-z]+_(dv|oa)_ids$
^ matches at the start of the line the regex pattern is applied to.
[0-9a-z] matces alphabetic and numeric chars.
+ means that there should be one or more chars in this set
(dv|oa) matches dv or oa
$ matches at the end of the string the regex pattern is applied to.
also matches before the very last line break if the string ends with a line break.
Give /\Amc_\w*_(oa|dv)_ids\z/ a try. \A is the beginning of the string, \z the end. \w* are one or more of letters, numbers and underscores and (oa|dv) is either oa or dv.
A nice and simple way to test Ruby Regexps is Rubular, might have a look at it.
This should work
/mc_834([a-z,0-9]*)_(oa|dv)_ids/g
Example: http://regexr.com?2v9q7

Resources