Regular expression for password validation - Objective C - ios

I need a regular expression that can validate following cases,
Be 8 to 20 characters
Use at least 1 upper case letter, 1 lower case letter, and 1 number
Not repeat the same number or letter more than 3 times in a row
Not contain spaces, and may only use these characters
# # * ( ) + = { } / ? ~ ; , . - _
The closest solution I can find is
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z])(?=.*[#(#*){+=}/?~;,._]).{8,20}$
But contains following issue,
Accepting space
Can't add - character
Repeating same number or letter more than 3 times in a row.
EDIT: Fixed the repeating character issues and have final expression like,
^(?!.*?(.)\1{3})(?!.* )(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[:£€&"!'[\]%^\|<>$]).{8,20}$
But its only working on online tester like [RegExr][1]
I tried following code but it generates runtime
- (BOOL)string:(NSString *)text matches:(NSString *)pattern{
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSArray *matches = [regex matchesInString:text options:0 range:NSMakeRange(0, text.length)];
return matches.count > 0;
}

Related

One uppercase letter validation regex

I am working on a regex validation for an alphanumeric character with a length of 4 but contains only one Uppercase letter.
This is the code I have:
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:#"(?=.*[0-9])(?=.*[A-Z])[a-zA-Z0-9]{4}" options:NSRegularExpressionCaseInsensitive error:&error];
However, it does not perform the check correctly. How can I do it?
Change your pattern like this,
#"^(?=.*[0-9])(?=[^A-Z]*[A-Z][^A-Z]*$)[a-zA-Z0-9]{4}$"
I think this would be enough for you
#"^(?=.*\\d)(?=.*[A-Z]).{4}$"
Or if you want to give minimum and maximum length then use below snippet
#"^(?=.*\\d)(?=.*[A-Z]).{4,15}$"
Here 4 would be the minimum length and 15 would be maximum length for your string
If you need to differentiate upper- and lowercase letters, you need to remove NSRegularExpressionCaseInsensitive option. It removes the differentiation between the lower and upper case.
Once you remove it, the following regex (if you need to support Unicode letters):
#"\\A(?=\\D*\\d)(?=\\P{Lu}*\\p{Lu}\\P{Lu}*\\z)[\\p{L}\\d]{4}\\z"
Or just ASCII:
#"\\A(?=\\D*\\d)(?=[^A-Z]*[A-Z][^A-Z]*\\z)[A-Za-z\\d]{4}\\z"
See another regex demo
NSRegularExpression *expression = [
NSRegularExpression regularExpressionWithPattern:#"\\A(?=\\D*\\d)(?=[^A-Z]*[A-Z][^A-Z]*\\z)[A-Za-z\\d]{4}\\z"
options:0
error:&error];
Regex breakdown:
\A - unambigous start of string
(?=\D*\d) - check if there is at least 1 digit after 0 or more non-digits (\D*)
(?=\P{Lu}*\p{Lu}\P{Lu}*\z) - check if there is ONLY 1 uppercase letter (\p{L}) in-between 0 or more any characters other than uppercase letters (\P{Lu})
[\p{L}\d]{4} - exactly 4 characters that are either a letter (lower- or uppercase) or a digit.
\z - match unambigous end of string.
IDEONE demo resulting in "yes":
NSString * s = #"e3Df";
NSString * rx = #"\\A(?=\\D*\\d)(?=[^A-Z]*[A-Z][^A-Z]*\\z)[A-Za-z\\d]{4}\\z";
NSPredicate * predicat = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", rx];
if ([predicat evaluateWithObject:s]) {
NSLog (#"yes");
}
else {
NSLog (#"no");
}

How to replace strings using regex in objective C?

I have a string that sometimes contains strings like: #"[id123123|Some Name]"
What I have to do, is to simply replace it to "Some Name"
For example I have string: Some text lalala blabla [id123|Some Name] bla bla bla
And I need to get: Some text lalala blabla Some Name bla bla bla
The question is how to? My mind tells me that I can do this with NSRegularExpression
Look into stringByReplacingOccurrencesOfString:withString:options:range:. The options: allow the search string to be a regular expression pattern.
Not an Objective C person, but judging from this previous SO post, you could use a regex like so:
NSString *regexToReplaceRawLinks = #"\\[.+?\\|(.+?)\\]";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexToReplaceRawLinks
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *string = #"[id123|Some Name]";
NSString *modifiedString = [regex stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"$1"];
This should match the string you are using and place the name in a group. You then replace the entire string [id123|Some Name] with Some Name.
Regex101
(\[[^|]+|([^\]]+]))
Description
\[ matches the character [ literally
[^|]+ match a single character not present in the list below
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
| the literal character |
\| matches the character | literally
1st Capturing group ([^\]]+])
[^\]]+ match a single character not present in the list below
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
\] matches the character ] literally
] matches the character ] literally
In capture group 1 is the thing you want to replace with what is in capture group 2. enjoy.

iOS - NSString regex match

I have a string for example:
NSString *str = #"Strängnäs"
Then I use a method for replace scandinavian letters with *, so it would be:
NSString *strReplaced = #"Str*ngn*s"
I need a function to match str with strReplaced. In other words, the * should be treated as any character ( * should match with any character).
How can I achieve this?
Strängnäs should be equal to Str*ngn*s
EDIT:
Maybe I wasn't clear enough. I want * to be treated as any character. So when doing [#"Strängnäs" isEqualToString:#"Str*ngn*s"] it should return YES
I think the following regex pattern will match all non-ASCII text considering that Scandinavian letters are not ASCII:
[^ -~]
Treat each line separately to avoid matching the newline character and replace the matches with *.
Demo: https://regex101.com/r/dI6zN5/1
Edit:
Here's an optimized pattern based on the above one:
[^\000-~]
Demo: https://regex101.com/r/lO0bE9/1
Edit 1: As per your comment, you need a UDF (User defined function) that:
takes in the Scandinavian string
converts all of its Scandinavian letters to *
takes in the string with the asterisks
compares the two strings
return True if the two strings match, else false.
You can then use the UDF like CompareString(ScanStr,AsteriskStr).
I have created a code example using the regex posted by JLILI Amen
Code
NSString *string = #"Strängnäs";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[^ -~]" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#"*"];
NSLog(#"%#", modifiedString);
Output
Str*ngn*s
Not sure exactly what you are after, but maybe this will help.
The regular expression pattern which matches anything is. (dot), so you can create a pattern from your strReplaced by replacing the *'s with .'s:
NSString *pattern = [strReplaced stringByReplacingOccurencesOfString:#"*" withString:"."];
Now using NSRegularExpression you can construct a regular expression from pattern and then see if str matches it - see the documentation for the required methods.

Objective C - Trim spaces from end of each line of a string

I have a string like this:
NSString* text = #" Line 1 \n Line 2 \n Line 3 ";
and I have to trim only the spaces of the end of each line, like this:
text = #" Line 1\n Line 2\n Line 3";
How can I do this using regular expression?
This question is not duplicated because the other posts removes only the spaces at the end of the string, not at the end of each line of the same string, and it is using regex.
Use this simple regex: (?m) +$
Sample Code
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(?m) +$" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *result = [regex stringByReplacingMatchesInString:subject options:0 range:NSMakeRange(0, [subject length]) withTemplate:#""];
Explanation
(?m) turns on multi-line mode, allowing ^ and $ to match on each line
+ matches one or more space characters
The $ anchor asserts that we are at the end of the string

regular expression in iOS

I am looking for a regular expression to match the following -100..100:0.01. The meaning of this expression is that the value can increment by 0.01 and should be in the range -100 to 100.
Any help ?
You could use NSRegularExpression instead. It does support \b, btw, though you have to escape it in the string:
NSString *regex = #"\\b-?1?[0-9]{2}(\\.[0-9]{1,2})?\\b";
Though, I think \\W would be a better idea, since \\b messes up detecting the negative sign on the number.
A hopefully better example:
NSString *string = <...your source string...>;
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"\\W-?1?[0-9]{2}(\\.[0-9]{1,2})?\\W"
options:0
error:&error];
NSRange range = [regex rangeOfFirstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
NSString *result = [string substringWithRange:range];
I hope this helps. :)
EDIT: fixed based on the below comment.
(\b|-)(100(\.0+)?|[1-9]?[0-9](\.[0-9]{1,2})?\b
Explanation:
(\b|-) # word boundary or -
( # Either match
100 # 100
(\.0+)? # optionally followed by .00....
| # or match
[1-9]? # optional "tens" digit
[0-9] # required "ones" digit
( # Try to match
\. # a dot
[0-9]{1,2}# followed by one or two digits
)? # all of this optionally
) # End of alternation
\b # Match a word boundary (make sure the number stops here).
Why do you want to use a regular expression? Why not just do something like (in pseudocode):
is number between -100 and 100?
yes:
multiply number by 100
is number an integer?
yes: you win!
no: you don't win!
no:
you don't win!
if(val>= -100 && val <= 100)
{
NSString* valregex = #"^[+|-]*[0-9]*.[0-9]{1,2}";
NSPredicate* valtest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", valregex];
ret = [valtest evaluateWithObject:txtLastname.text];
if (!ret)
{
[alert setMessage:NSLocalizedString(#"More than 2 decimals", #"")];
[alert show];
}
}
works fine.. Thnx for the efforts guys !

Resources