Regular expression to match multiple occurrences of characters between delimiters - objective-c

I'm trying to use NSRegularExpression to find multiple occurrences of substrings that are delimited by a pair of % characters, for example if I want to extract "%FirstOccurence%enter code here" as a substring from the following:
"stuff %FirstOccurence% more stuff"
Then I can do this:
NSString* const pattern = #"[%].+[%]";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:0
error:nil];
NSRange range = NSMakeRange(0, [testData length]);
NSTextCheckingResult *textCheckingResult = [regex firstMatchInString:testData options:0 range: range];
However if the string contains something like this:
"stuff %FirstOccurence% more stuff %Second Occurrence% yet more stuff"
Then my regex will match this: "%FirstOccurence% more stuff %Second Occurrence%" i.e. the NSTextCheckingResult will contain one range.
What should the regex/code be to make the NSTextCheckingResult contain two ranges of %FirstOccurence% and %Second Occurrence% rather than the one larger range?

It appears you want to be calling matchesInString:options:range: which returns all the matching results.
NSArray *matches = [regex matchesInString:string
options:0
range:NSMakeRange(0, [string length])];
See https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSRegularExpression

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

How delete all symbols from string except letters and numbers?

I am trying use next code:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[\\p{L}[0-9]]+|-" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#""];
but it doesn't work. I use different variations of this, but without success too.
Example text:
Это тестовый.!!?! ;$%###### (вопрос) номер 1256 - верно.
Example output:
Это тестовый вопрос номер 1256 - верно
Your regex is actually matching characters you want to remove, but it is corrupt and does not even do that (due to a "wild" ]).
If you need to delete all chars except letters, digits, hyphens and whitespaces, use #"[^\\p{L}\\p{M}0-9\\s-]+".
Details:
[^\\p{L}\\p{M}0-9\\s-]+ - one or more characters that are NOT:
\\p{L} - Unicode letters
\\p{M} - diacritics
0-9 - ASCII digits
\\s - whitespace
- - a literal hyphen.
See the online Objective-C demo:
NSString *text = #"Это тестовый.!!?! ;$%###### (вопрос) номер 1256 - верно";
NSError *error = NULL;
NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:#"[^\\p{L}\\p{M}0-9\\s-]+" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *result = [regexp stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:#""];
NSLog(result);
Result: Это тестовый вопрос номер 1256 - верно
1st find the num-alphabet set:
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
2nd get the invert set of it, and we will use it as separators:
NSCharacterSet *separatorSet = [alphaSet invertedSet];
3nd use separator to separate the old string and then join characters back together with #"":
NSString *newString = [[oldString componentsSeparatedByCharactersInSet: separatorSet]componentsJoinedByString:#""];'

Objective C - Split string into array

How would I do this? I'm new to Objective-C but I can't find anything that would help me do this.
NSArray *splitLine = [currentLine componentsSeparatedByString:#":%#",notNumber];
Where notNumber is a string that represents anything that isn't a number. So I want to separate a string where there are colons separated by strings that aren't numbers. (I want to avoid splitting at times i.e. 3:00pm, but split at iCal parameters like DESCRIPTION: and LOCATION:.)
You can do this in several steps, like this. I have not compiled this code, but it should at least give you an idea of what to do.
1) Create a regex object to match your separators:
NSString *regexString = #"DESCRIPTION:\s|LOCATION:\s"; // or whatever makes sense for your scenario
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regexString
options:NSRegularExpressionCaseInsensitive
error:nil];
2) Replace all the different separators matching your regex with just one separator:
NSRange range = NSMakeRange(0, string.length);
NSString *string2 = [regex stringByReplacingMatchesInString:string
options:0
range:range
withTemplate:#"SEPARATOR"];
3) Split the string!
NSArray *elements = [string2 componentsSeparatedByString:#"SEPARATOR"];
Shortest solution for splitting string.
NSString *str = #"Please split me to form array of words";
NSArray *wordsArray = [str componentsSeparatedByString:#" "];
You can use regular expressions!
Using the pattern (I believe this is the core of your question):
pattern = #"(?<=[^0-9]):(?=[^0-9])"
This pattern will only match ':' symbols not surrounded by numbers.
Then replace with a dummy value that won't show in your data
dummy = #"NEVERSEETHIS"
NSRegularExpressions *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
NSRange range = NSMakeRange(0, [string length])
NSString *modified= [regex replaceMatchesInString:yourString options:0 range:range withTemplate:dummy];
and finally, split
return [modified componentsSeparatedByString:dummy];

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.