NSRegularExpression for an array of array? - objective-c

I have the following code:
//NSMutableArray sections - contains some data;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[a-c]" options:0 error:NULL];
[sections enumerateObjectsUsingBlock:^(NSString * str, NSUInteger idx, BOOL * stop) {
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
if (match) {
[filteredList addObject:match];
}
}];
In this case sections is a NSMutableArray.
How should i change the code if sections would be an NSMutableArray of NSMutableArrays?
If curently sections is a NSMutableArray how can I declare a NSMutableArray of NSMutableArrays of sections?

Related

How can I replace strings between a pattern for an NSString?

Consider an NSString of the following pattern:
(foo('Class 0')bar('Class 1')baz('Class 2')
I just need to return foo, bar and baz. Any way I could at least replace 'Class 0' to some single character using regex?
I tried:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\(.*?\\)"
options:NSRegularExpressionCaseInsensitive
error:nil];
text = [regex stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:#""];
If I understood your situation correctly, you needed to parse foo, bar, and baz out of the string above. The code below will do just that, and return foo, bar, and baz in an array.
As you will see in the code, we match on a word and an opening paren, and then trim the parens off programmatically. There may be a better regex that doesn't require the trimming, but I couldn't make that work with NSRegularExpression.
NSString *text = #"(foo('Class 0')bar('Class 1')baz('Class 2')";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[a-z]+[\(]"
options:NSRegularExpressionCaseInsensitive
error:nil];
NSMutableArray *output = [[NSMutableArray alloc] init];
[regex enumerateMatchesInString:text
options:0
range:NSMakeRange(0, [text length])
usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
NSString *rawMatch = [text substringWithRange:result.range];
NSString *trimmed = [rawMatch substringToIndex:(rawMatch.length - 1)];
[output addObject:trimmed];
}];
To get a string, like the one you mention in your comment above, just use
NSString *finalString = [output componentsJoinedByString:#" "];
I would just use:
NSString *string = #"foo('Class 0')bar('Class 1')baz('Class 2')";
NSString *output = [string stringByReplacingOccurrencesOfString:#"\\('[^')]*'\\)"
withString:#" "
options:NSRegularExpressionSearch
range:NSMakeRange(0, string.length)];
NSLog(#"%#", output); // foo bar baz
Replacing anything between (' and ') with a space. The pattern [^')] means that we don't want ) and 'letters to appear in between.

Trim an NSString Based Upon Number Of Character Occurrences

I'm trying to trim an NSString after I detect 3 new line instances. (\n). So, this is what I've tried:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\n" options:NSRegularExpressionCaseInsensitive error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [myString length])];
Now, number of matches will always exceed 3, and I want to stop the string right as it hits the third \n. Does any one know any good logic to do this?
If the 3 new line instances are always grouped together it's pretty easy:
NSString *testString = #"The quick brown fox jumps \n\n\n over the lazy dog. \n\n\n New Line.";
[[string componentsSeparatedByString:#"\n\n\n"] firstObject]
Otherwise you could use:
NSError *error;
NSString *pattern = #"(\\A|\\n\\s*\\n\\s*\\n)(.*?\\S[\\s\\S]*?\\S)(?=(\\Z|\\s*\\n\\s*\\n\\s*\\n))";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:testString
options:0
range:NSMakeRange(0, [testString length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSString *match = [testString substringWithRange:[result rangeAtIndex:2]];
NSLog(#"match = '%#'", match);
}];
(Taken from this answer)
NSString* originalString = #"This\nis\na\ntest string";
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:#".*\\n.*\\n.*\\n" options:0 error:nil];
NSRange range = [regex rangeOfFirstMatchInString:originalString options:0 range:(NSRange){0,originalString.length}];
NSString* trimmedString = [originalString substringFromIndex:range.length];
NSLog(#"Original: %#", originalString);
NSLog(#"Trimmed: %#", trimmedString);
Prints:
2015-02-05 21:39:41.491 TestProject[4258:1269568] Original: This
is
a
test string
2015-02-05 21:39:41.492 TestProject[4258:1269568] Trimmed: test string

Printing particular value from NSString

NSDictionary* headers; = [(NSHTTPURLResponse *)response allHeaderFields];
NSString *str;= [headers objectForKey:#"Www-Authenticate"];
NSLog(#"value:%#",str);
value:First aid="my server part", qop="accept", nonce="nyeraAT567WE"
I want to get and print only nonce
You need a regex to extract it:
NSError *error=nil;
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:#"nonce=\"(.*)\"" options:0 error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
NSString *nonce = [str substringWithRange:[match rangeAtIndex:1]];
NSLog(#"%#",nonce);

how to use regular expressions NSRegularExpression for an NSMutableArray

I have the following code which works:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[a-cA-C2][m-oM-O][a-cA-C2]" options:0 error:NULL];
NSString *str = #"Ana";
NSTextCheckingResult *match1 = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
NSLog(#"check is exist: %#", [str substringWithRange:[match1 rangeAtIndex:0]]);
Here are my questions:
1.Is there a way I can change the NSString with an NSMutableArray and save the NSTextCheckingResult in a NSMutableArray called filterArray?
2.How to highlight the matching values when displaying then in a TextField?
If I correctly understand your question,
you want to use NSArray of strings, and receive NSArray of matching results for each string.
So, 1:
NSArray *arrayOfStrings = /* Your array */;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[a-cA-C2][m-oM-O][a-cA-C2]" options:0 error:NULL];
NSMutableArray *filterArray = [NSMutableArray array];
[arrayOfStrings enumerateObjectsUsingBlock:^(NSString * str, NSUInteger idx, BOOL * stop) {
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
if (match) {
[filterArray addObject:match];
}
else {
[filterArray addObject:[NSNull null]];
}
NSLog(#"String #%i. check is exist: %#",idx, [str substringWithRange:[match rangeAtIndex:0]]);
}];
2: For highlighting ranges of the string you need to use NSAttributedString. Please, see this question for the answer how:) How do you use NSAttributedString?
After you formed attributed string, set it to textfield:
NSAttributedString * attributedString;
UITextField *textField;
[ttextField setAttributedText:attributedString];

regex to extract all the substrings between two characters or tags

I need to extract all the strings surrounded by two characters (or maybe two tags)
this is what I've done so far:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\[(.*?)\\]" options:NSRegularExpressionCaseInsensitive error:NULL];
NSArray *myArray = [regex matchesInString:#"[db1]+[db2]+[db3]" options:0 range:NSMakeRange(0, [#"[db1]+[db2]+[db3]" length])] ;
NSLog(#"%#",[myArray objectAtIndex:0]);
NSLog(#"%#",[myArray objectAtIndex:1]);
NSLog(#"%#",[myArray objectAtIndex:2]);
In myArray there are correctly three objects but NSlog prints this:
<NSSimpleRegularExpressionCheckingResult: 0x926ec30>{0, 5}{<NSRegularExpression: 0x926e660> \[(.*?)\] 0x1}
<NSSimpleRegularExpressionCheckingResult: 0x926eb30>{6, 5}{<NSRegularExpression: 0x926e660> \[(.*?)\] 0x1}
<NSSimpleRegularExpressionCheckingResult: 0x926eb50>{12, 5}{<NSRegularExpression: 0x926e660> \[(.*?)\] 0x1}
instead of db1, db2 and db3
where I'm wrong?
According to the documentation matchesInString:options:range: returns an array of NSTextCheckingResults not NSStrings. You will need to loop over the results and use the ranges to get the substrings.
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\[(.*?)\\]" options:NSRegularExpressionCaseInsensitive error:NULL];
NSString *input = #"[db1]+[db2]+[db3]";
NSArray *myArray = [regex matchesInString:input options:0 range:NSMakeRange(0, [input length])] ;
NSMutableArray *matches = [NSMutableArray arrayWithCapacity:[myArray count]];
for (NSTextCheckingResult *match in myArray) {
NSRange matchRange = [match rangeAtIndex:1];
[matches addObject:[input substringWithRange:matchRange]];
NSLog(#"%#", [matches lastObject]);
}
Or this
NSArray *results = [#"[db1]+[db2]+[db3]" matchWithRegex:#"\\[(.*?)\\]"];
//result = #["db1","db2,"db3"]
With this category https://github.com/damienromito/NSString-Matcher