NSRegularExpression not matching - objective-c

So I have a string:
users/9881570/?access_token=
that I try to match with the regex:
NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:#"users/\\d/?access_token=" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray* wordArray = [regex matchesInString:self.currentRequestURL_
options:0 range:NSMakeRange(0, [self.currentRequestURL_ length])];
However, the wordArray has a count of 0. Why is this not matching?

For one thing, you need to escape the question mark, and for another you need a plus sign (+) after your \d to indicate 1 or more numbers. As it is now you only look for one digit.
#"users/\\d+/\\?access_token="

Because the question mark is a special character in regular expressions, and it needs to be escaped.

Related

Regex number of matches is always zero

I want to check a UITextField text with a format like "G12-123456".
Rules are simple;
First character must be upper case letter.
The 2nd and 3rd must be number.
Fourth must be "-" character.
The last six must be only numbers.
Below code not work, number of matches always returns zero.
I also tried regex as "[A-Z0-9]{3}-[0-9]{6}"
NSString * myRegex = #"[A-Z][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:myRegex
options:NSRegularExpressionCaseInsensitive
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:NSMatchingReportProgress
range:NSMakeRange(0, [string length])];
This one works with same code [^a-zA-Z0-9] -> Check whether an NSString contains a special character and a digit.
Any help would be appreciated.
First of all basically your code is supposed to work.
However both options are nonsensical. If you want to check for uppercase letter you must not pass NSRegularExpressionCaseInsensitive and NSMatchingReportProgress affects only the block based API.
In both cases pass 0.
The pattern can be written more efficient
NSString *myRegex = #"[A-Z]\\d{2}-\\d{6}";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:myRegex
options:0
error:&error];
if {error) {
NSLog(#"%#", error);
} else {
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
NSLog(#"%lu", numberOfMatches);
}
If the regex must match the entire string add the start - end anchors.
NSString *myRegex = #"^[A-Z]\\d(2)-\\d{6}$";
If numberOfMatches is zero please check if the hyphen character is the standard one (ASCII 45, hex 0x2D).

Is there any way to split a string into multiple string based on character count (not delimiter)?

So if I have "7A7F6E88920AB8271A" and I want to split it into an array of strings with same amount of character count, like "7A", "7F", "6E", "88", ... is there any method ready for this, or I have to manually make it on objective C? Thanks.
I am not an objective-c expert, but the following might lead you in the right direction (Regular Expressions)
NSRegularExpression regexp = [NSRegularExpression
regularExpressionWithPattern:#"(\\w){2}"
options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:string options:0
range:NSMakeRange(0, [string length])];
The RegExp (\\w){2}should find all 2-length character words and each of them are in the matches array.
Constructed from examples on this page: https://developer.apple.com/reference/foundation/nsregularexpression

RegEx (replaceMatchesInString) does not work

Why does this RegEx with replaceMatchesInString return only "+" instead of "+123"?
NString *phoneNumberCleaned = [NSString stringWithFormat:#"++00123"];
NSString *strRegExPhoneNumberPrefixWrong = #"^([+0]*)\\d*$";
NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern:strRegEx options:0 error:nil];
[regEx replaceMatchesInString:phoneNumberCleaned options:0 range:NSMakeRange(0, [phoneNumberCleaned length]) withTemplate:#"+"];
return phoneNumberCleaned;
Thanks
NSString *string = #"++00123";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"^[+0]+(?=\\d*)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *modifiedString = [regex
stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"+"];
return modifiedString;
The problem with your Regex was that ^([+0]*)\\d*$ is also matching the \d* which means, that it also gets replaced (you'd think that it would only replace your capture group, but evidently that isn't so). So you were essentialy replacing any string that matches the above pattern (which was including any trailing numbers), which in your case was the entire number.
What I used in my answer is called a positive lookahead.
^[+0]+(?=\\d*)$
The lookahead basically means that you're looking for zero or more + or 0 that are followed by zero or more digits EXCLUDING the digits from the match. So you only replace the zeroes and pluses, not the digits following them.

Dealing with separation characters within quotes when using componentsSeparatedByCharactersInSet

I'm trying to separate a string by the use of a comma. However I do not want to include commas that are within quoted areas. What is the best way of going about this in Objective-C?
An example of what I am dealing with is:
["someRandomNumber","Some Other Info","This quotes area, has a comma",...]
Any help would be greatly appreciated.
Regular expressions might work well for this, depending on your requirements. For example, if you're always trying to match items that are enclosed in double quotes, then the it might be easier to look for the quotes rather than worrying about the commas.
For example, you could do something like this:
NSString *pattern = #"\"[^\"]*\"";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = [match range];
NString *substring = [string substringWithRange:matchRange];
// do whatever you need to do with the substring
}
This code looks for a sequence of characters enclosed in quotes (the regex pattern "[^"]*"). Then for each match it extracts the matched range as a substring.
If that doesn't exactly match your requirements, it shouldn't be too difficult to adapt it to use a different regex pattern.
I'm not in a position to test this code at the moment, so my apologies if there are any errors. Hopefully the basic concept should be clear.

Regex stringByReplacingMatchesInString

I'm trying to remove any non-alphanumeric character within a string. I tried the following code snippet, but it is not replacing the appropriate character.
NSString *theString = #"\"day's\"";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^\\B\\W^\\B" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *newString = [regex stringByReplacingMatchesInString:theString options:0 range:NSMakeRange(0, [theString length]) withTemplate:#""];
NSLog(#"the resulting string is %#", newString);
Since there'e a need to preserve the enclosing quotation marks in the string, the regex necessarily becomes a bit complex.
Here is one which does it:
(?:(?<=^")(\W+))|(?:(?!^")(\W+)(?=.))|(?:(\W+)(?="$))
It uses lookbehind and lookahead to match the quotation marks, without including them in the capture group, and hence they will not be deleted in the substitution with the empty string.
The three parts handle the initial quotation mark, all characters in the middle and the last quotation mark, respectively.
It is a bit pedestrian and there has to be a simpler way to do it, but I haven't been able to find it. Others are welcome to chime in!
NSString *theString = #"\"day's\"";
NSString *pattern = #"(?:(?<=^\")(\\W+))|(?:(?!^\")(\\W+)(?=.))|(?:(\\W+)(?=\"$))";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: pattern
options: 0 // No need to specify case insensitive, \W makes it irrelevant
error: &error];
NSString *newString = [regex stringByReplacingMatchesInString: theString
options: 0
range: NSMakeRange(0, [theString length])
withTemplate: #""];
The (?:) construct creates a non-capturing parenthesis, meaning that you can keep the lookbehind (or lookahead) group and "real" capture group together without creating an actual capture group encapsulating the whole parenthesis. Without that you couldn't just substitute an empty string, or it would all be deleted.