I have a CoreData table with a field holding a string of a series of numbers separated by commas. I want to be able to run a fetch with a predicate that will match against a given specific number.
For example if fieldName = "12,52,66,89,2,8"
And I want to search for 2, then it should match the second to last number in the string and include that record in the results.
Using the regular expression:
^2|,2,|,2
I have found it working satisfactorily for my test cases, testing it using this site for example: https://www.regexpal.com/
However, when I pass this into an NSPredicate for a NSFetchRequest, I can't get it to match
NSNumber *val = #2;
NSString *regex = [NSString stringWithFormat:#"^%#|,%#,|,%#", val, val, val];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"fieldName MATCHES %#", regex];
Replacing the MATCHES with a CONTAINS val makes it work, but of course it will also incorrectly match any occurrence of the digits.
I suspect I am missing something stupid about formatting for CoreData (or regex), but I've tried many variations, and I'm hoping a kind soul reading this will put me out of my misery :)
Disclaimer: I haven't used Objective C. This answer is based on my regex knowledge and some documentation.
MATCHES
The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
That sounds like how Java uses the method "matches" in which case "^2|,2,|,2" can never match the entire string. This differs from regexpal which will always search the text. The regex you would need is more like
.*\b2\b.*
(the ^$ are assumed in Java). Another option is to split the string.
Related
I am using the regex ((.*)?:)?(.*)\\/([0-9]+|[n])? to match pattern of type module:function/arity, where arity can be any number >= 0 or the string n.
Success cases should match:
foo:bar/1
bar/1
foo:bar/0
foo:bar/n
bar/n
This seems to work fine at https://regex101.com/r/AtI5Nw/3, but using the following code, I am getting only one match group for "mod:func/1".
+ (NSArray<NSTextCheckingResult *> *)matchesInString:(NSString *)string withExpression:(NSRegularExpression *)pattern {
return [pattern matchesInString:string options:0 range:NSMakeRange(0, [string length])];
}
I tried with "mod:func/1" string and I am getting only one match. How to get all matching groups as in the screenshot? I want to get the module, function and arity parts from the string.
It's been awhile since I've done this, but...
matchesInString:... returns an array of NSTextCheckingResult objects. Each object represents a single match of the entire regex within the string.
Each NSTextCheckingResult object encapsulates a number of "ranges" (see numberOfRanges property). You then use rangeAtIndex: to extract the range of each group within that match instance.
If each target is in a separate string, you don't need matchesInString:..., simply use firstMatchInString:... to obtain the one, and only, NSTextCheckingResult for your string. You can then extract each group by getting its range, then return to the original string to extract the text of that component.
I'm working on a small iOS App and got stuck with creating a pattern using NSRegularExpression class. I need a pattern that I can use to look for and match a special word and replace it later but I need to exclude this word from match in case it has already been replaced by this match. So if user processes given text several times the replacement goes only once.
Example:
I need to find and replace all "yes" in any given text with "probably yes". But I need to exclude replacement of "yes" in "probably yes" in case user processes text one more time so it won't look like "probably probably yes"
NSRegularExpression *regexYesReplace = [NSRegularExpression regularExpressionWithPattern:#"some pattern" options:0 error:&error];
NSString *replacementStringYesReplace = #"probably yes";
replacedText = [regexYesReplace stringByReplacingMatchesInString:afterText options:options range:range withTemplate:replacementStringYesReplace];
I tried to implement pattern from this question and fixed syntax for NSRegularExpression but it didn't work out.
Regex replace text but exclude when text is between specific tag
May be someone had the same problem. Thanks in advance
You can use negative look-behind
(?<!probably )yes
Regex Demo
I have a little problem with NSRange and rangeOfString. I want to search a substring in a given string which is working fine, but only to find a exact string and theres the problem i need to find a substring which begins always the same and ends always the same. I tried it already with something like that:
match = [strIn rangeOfString: #"truni/begin/*/end"];
But thats not working. So i need a way to to do this. Here is the specific part of the Code in full:
NSRange match;
match = [strIn rangeOfString: #"turni/begin/sHjeUUej/end"];
NSRange range = NSMakeRange(match.location, match.length);
NSString *strOut = [strIN substringWithRange:range];
You see the string "turni/begin/sHjeUUej/end" will always be the same except for the part "sHjeUUej". Hope someone can help me.
Thanks in advance.
Use a regular expression with:
- (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask
with an option of RegularExpressionSearch.
See ICU User Guide Regular Expressions for information on creating regular expressions.
you can use prefix/suffix
if ([strIn hasPrefix:#"truni/begin/"] && [strIn hasSuffix:#"end"]) {
//match
You can use a simpler solution if you make sure that your string always starts with turni/begin/ and ends with /end.
You can use:
NSString *strOut = [[strIn stringByReplacingOccurrencesOfString:#"turni/begin/" withString:#""] stringByReplacingOccurrencesOfString:#"/end" withString:#""];
With that, you can retrieve the string between the two others with only one line of code and less comparations.
I haven't used regular expressions yet in objective-c. What I'm trying to do right now is evaluate a string to see if it contains a 4 or 5 character repeating pattern - any pattern, it doesn't matter. For instance, a string like #"testA54RqA54Rq" would return a true value from the regex, while a string like #"testA54Rq" would not. Right now I'm just generating all possible 4 and 5 character substrings and matching them to each other, but obviously this is extremely inefficient. Where can I find some resources about how to start using regular expressions in objective C? If anyone's been in this situation before a small example would be nice.
-EDIT-
I would also like to have somthing like #"testQWEr30BKRe40" return true (pattern of 4 letters followed by 2 numbers). I'm not sure if this is possible.
You probably want to look at:
https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
The actual regex I believe would just be: (\\w{4,5})\\1
NSString *regexStr = #"(\\w{4,5})\\1";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexStr options:0 error:&error];
if ((regex==nil) && (error!=nil)) {
warn( #"Regex failed for: %#, error was: %#", string, error);
} else {
}
For exact patterns you will be able to do such validation with regex (.{4,5})\\1
If you want to do category pattern, such as 4 letters followed by 2 numbers, then you have to:
replace all letters with one constant letter (for example replace [a-zA-Z] with X)
replace all numbers with one constant number (for example replace \\d with 0)
validate such modified input with the same regex as shown above
I'm trying to get some info out of a document. I'm trying to match the info I need with regex, which matches 3 numbers within a string. It works fine, but it only matches the first occurance. I need it to match an unlimited number of times because I don't know how many times this string will occur.
NSString *regex = #"String containing data:(\\d+) and more data:(\\d+) and so on";
NSArray *captures = [document captureComponentsMatchedByRegex:regex];
for(NSString *match in captures){
NSLog(#"%#",match);
}
The above code prints out 3 strings - The entire string, the first data and the second data. All good, but now I need it to keep searching the document, because similar strings will occur n times.
How do I do this? And is there any way to group the matches into an array for each string or something like that?
Use the arrayOfCaptureComponentsMatchedByRegex: method. That will return an NSArray of NSArray objects, and each nested NSArray object will have the captures (index 0 being the string, index 1 being the first capture, etc).