NSRegularExpression enumerateMatchesInString correct usage - objective-c

My string looks like this:
dog-3
dog-2
dog-1
dog0
aaaaaaa
dog1
dog2
dog3
dog4
bbbbbbb
dog5
dog6
dog7
dog8
ccccccc
dog9
dog10
dog11
aaaaaaa
dog12
dog13
dog14
dog15
bbbbbbb
dog16
dog17
dog18
dog19
ccccccc
dog20
dog21
dog22
dog23
I am trying to write a regular expression to match a pattern "^aaaaaaa$.+^bbbbbbb$.+^ccccccc"
This is my code where str is described above
NSRegularExpression *conflictMarker = [NSRegularExpression regularExpressionWithPattern:#"^aaaaaaa$.+^bbbbbbb$.+^ccccccc"
options:NSRegularExpressionDotMatchesLineSeparators|NSRegularExpressionAnchorsMatchLines
error:&error];
[conflictMarker enumerateMatchesInString:str options:0
range:NSMakeRange(0, str.length)
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange matchRange = [result range];
NSString *subst = [str substringWithRange:matchRange];
NSInteger a = result.numberOfRanges;
NSLog(#"%ld ", a);
for (NSInteger a = 0; a < result.numberOfRanges; a++) {
NSRange matchRange = [result rangeAtIndex:a];
NSString *subst = [str substringWithRange:matchRange];
NSLog(#"\n%#", subst);
}
}];
My expectation from the above code was to receive two matches; the first match contains a range from "dog1" to "dog8" and second range from "dog12" to "dog19" but I only get 1 match with a range from "dog1" to "dog19".
What am I doing wrong here and how can I correct it?
Thanks in advance.

You may use
^aaaaaaa(?:\R(?!(?:bbbbbbb|aaaaaaa|ccccccc)$).*)*\Rbbbbbbb(?:\R(?!(?:aaaaaaa|ccccccc)$).*)*\Rccccccc
See the regex demo. Make sure you change the regex options to options:NSRegularExpressionAnchorsMatchLines for this pattern to work:
NSRegularExpression *conflictMarker = [NSRegularExpression regularExpressionWithPattern:#"^aaaaaaa(?:\\R(?!(?:bbbbbbb|aaaaaaa|ccccccc)$).*)*\\Rbbbbbbb(?:\\R(?!(?:aaaaaaa|ccccccc)$).*)*\\Rccccccc"
options:NSRegularExpressionAnchorsMatchLines
error:&error];
Details
^ - start of a line
aaaaaaa - a string
(?:\R(?!(?:bbbbbbb|aaaaaaa|ccccccc)$).*)* - 0 or more occurrences of
\R(?!(?:bbbbbbb|aaaaaaa|ccccccc)$) - a line break sequence that is not followed with bbbbbbb, aaaaaaa, or ccccccc and the end of a line
.* - any 0+ chars other than line break chars, as many as possible
\R - a line break sequence
bbbbbbb - a string
(?:\R(?!(?:aaaaaaa|ccccccc)$).*)* - 0 or more occurrences of
\R(?!(?:aaaaaaa|ccccccc)$) - a line break sequence that is not followed with aaaaaaa or ccccccc and the end of a line
.* - any 0+ chars other than line break chars, as many as possible
\R - a line break sequence
ccccccc - a string.

Related

Regex to reject sequence of Digits

I need to validate phone number. Below is the code snippet
-(BOOL) validatePhone:(NSString*) phoneString
{
NSString *regExPattern = #"^[6-9]\\d{9}$"; ORIGINAL
// NSString *regExPattern = #"^[6-9](\\d)(?!\1+$)\\d*$";
NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:nil];
NSUInteger regExMatches = [regEx numberOfMatchesInString:phoneString options:0 range:NSMakeRange(0, [phoneString length])];
NSLog(#"%lu", (unsigned long)regExMatches);
if (regExMatches == 0) {
return NO;
}
else
return YES;
}
I want to reject phone number that is in sequnce example
9999999999, 6666677777
It seems you want to disallow 5 and more identical consecutive digits.
Use
#"^[6-9](?!\\d*(\\d)\\1{4})\\d{9}$"
See the regex demo
Details
^ - start of string
[6-9] - a digit from 6 to 9
(?!\d*(\d)\1{4}) - a negative lookahead that fails the match if, immediately to the right of the current location, there is
\d* - 0+ digits
(\d) - a digit captured into Group 1
\1{4} - the same digit as captured in Group 1 repeated four times
\d{9} - any 9 digits
$ - end of string (replace with \z to match the very end of string do disallow the match before the final LF symbol in the string).
Note that \d is Unicode aware in the ICU regex library, thus it might be safer to use [0-9] instead of \d.

Apostrophes (') is not recognised in regular expression

I want a regular expression for first name that can contain
1)Alphabets
2)Spaces
3)Apostrophes
Exp: Raja, Raja reddy, Raja's,
I used this ^([a-z]+[,.]?[ ]?|[a-z]+[']?)+$ but it is failing to recognise Apostrophes (').
- (BOOL)validateFirstNameOrLastNameOrCity:(NSString *) inputCanditate {
NSString *firstNameRegex = #"^([a-z]+[,.]?[ ]?|[a-z]+[']?)+$";
NSPredicate *firstNamePredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES[c] %#",firstNameRegex];
return [firstNamePredicate evaluateWithObject:inputCanditate];
}
May I recommand ^[A-Z][a-zA-Z ']* ?
// The NSRegularExpression class is currently only available in the Foundation framework of iOS 4
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[A-Z][a-zA-Z ']*" options:NSRegularExpressionAnchorsMatchLines error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:searchText options:0 range:NSMakeRange(0, [string length])];
return numberOfMatches > 1;
^[A-Z] : Force start with a capital letter from A to Z
[a-zA-Z ']* : followed by any number of charactere that an be 'a' to 'z', 'A' to 'Z', space or simple quote
I think you are looking for a pattern like this: ^[a-zA-Z ']+$
However, this is pretty bad. What about umlauts, accents, and a whole lot other letters that are not part of the ASCII alphabet?
A better solution would be to allow any kind of letter from any language.
To do so you can use the Unicode "letter" category \p{L}, e.g. ^[\p{L}]+$.
.. or you could just drop that rule all together - as reasonably suggested.

how to replace in string using regex

I have below as string
name : abc,
position : 2
I want to make replace so that the string becomes as below
name : "abc",
position : 2
What change I want to do is abc will have double quotes so abc becomes "abc".
Note: abc is dynamic, it can be anything as below.
name : Test,
position : 2
name : Great,
position : 2
name : developers,
position : 2
Any idea how this can be done?
I suggest using \\b(name\\s*:\\s*)(.+), pattern and replace with $1"$2",:
NSError *error = nil;
NSString *myText = #"name : abc,\nposition : 2";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\b(name\\s*:\\s*)(.+)," options:nil error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:myText options:0 range:NSMakeRange(0, [myText length]) withTemplate:#"$1\"$2\","];
NSLog(#"%#", modifiedString);
See the Objective-C demo
Details:
\\b - a leading word boundary
(name\\s*:\\s*) - Group 1 matching name, 0+ whitespaces, : and 0+ whitespaces again
(.+) - any 0+ chars other than line break chars as many as possible
, - comma
The replacement pattern - $1"$2", - inserts Group 1 contents, ", Group 2 contents and ",.
See the regex demo.

Regex for numbers with optional decimal value, fixed to two positions?

I need to know if a string is in the following format:
Any number of integers followed by:
an optional group of:
a decimal followed by two digits (required if a decimal is provided)
This allows any number of digits, and I thought it was in the proper format to allow an optional group that consists of a period followed by two digits, but for some reason this doesn't allow the decimal. Perhaps the decimal isn't escaped appropriately?
#"^[0-9]+(\\.[0-9][0-9])?$"
I tried #"^[0-9]+(\.[0-9][0-9])?$" but Xcode throws a compile-time warning: Unknown escape sequence \..
I suggest using ^[0-9]+(?:\\.[0-9]{2})?$ regex (in Objective C, we need to escape regex backslash).
^ - String start
[0-9]+ - Any number of digits
(?:\\.[0-9]{2})? - Optional group:
\\. - A literal dot
[0-9]{2} - Exactly two digits
$ - String end
Here is a sample code you can use (it will report a match in this case):
NSString *pattern = #"^[0-9]+(?:\\.[0-9]{2})?$";
NSString *string = #"12345.20";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSRange textRange = NSMakeRange(0, string.length);
NSRange matchRange = [regex rangeOfFirstMatchInString:string options:NSMatchingReportProgress range:textRange];
// Did we find a matching range
if (matchRange.location != NSNotFound)
NSLog (#"YES! It is matched!");
else
NSLog (#"NO MATCH!");

NSRegularExpression string delimited by

I have a string for example #"You've earned Commentator and 4 ##other$$ badges". I want to retreive the substring #"other", which is delimited by ## and $$. I made a NSRegularExpression like this:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"##(.*)$$" options:NSRegularExpressionCaseInsensitive error:nil];
This completely ignores $$ and returns stuff starting with ##. What am I doing wrong? thanks.
Thats because '$' is a special character that represents the end of the line. Try \$\$ to escape it and tell the parser you want the characters.
I wouldn't use a regex in this situation, since the string bashing is so simple. No need for the overhead of compiling the expression.
NSString *source = #"You've earned Commentator and 4 ##other$$ badges";
NSRange firstDelimiterRange = [source rangeOfString:#"##"];
NSRange secondDelimiterRange = [source rangeOfString:#"$$"];
NSString *result = [source substringWithRange:
NSMakeRange(firstDelimiterRange.origin +2,
firstDelimiterRange.origin - secondDelimiterRange.origin)];