In iOS I need to check string against regular expression and if it passes then to return true (for example), if not false. I understand that I have to use NSRegularExpression class, but I can not figure out how.
You should read documentation.
Here is an example code how to do this in general:
- (BOOL)checkString:(NSString *)string {
NSString *const expression = #"^\\d{3}[-]\\d{2}[-]\\d{4}$"; // insert yours
NSError *error = nil;
NSRegularExpression * const regExpr =
[NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult * const matchResult = [regExpr firstMatchInString:string
options:0 range:NSMakeRange(0, [string length])];
return matchResult ? YES : NO;
}
Related
I am new to Regular Expressions and its usage in iOS .I have a scenario where I have to check whether a NSString starts with 'G' this is my function which returns the bool condition . I am passing the data like this
[self compareStringWithRegex:#"Gmail" withRegexPattern:#".*g"];
-(BOOL) compareStringWithRegex:(NSString *) string withRegexPattern:(NSString *)expression
{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
if (match){
return YES;
}else{
return NO;
}
}
The problem I am facing is, this function returns true if I give wrong condition . Please help me in this and let me know if my question is not clear .
If you want to use Regular Expressions to check string start with "g" then
replace ".*g" with "^g" it will give you asspected result
[self compareStringWithRegex:#"Gmail" withRegexPattern:#"^g"];
If you really want to use regex the #"(g)+(\\w+)" should work. I tested it on Regex Tester
Hi i am Trying to Match Characters in Words Same as Email Search while Sending Emails. Where popover is shown. By Typing text, Text is Highlighted in Popover.
Anna Haro
anna-haro#mac.com
Hank M. Zakroff
hank-zakroff#mac.com
what is Tried is,
\bHa[\w-]*
Expecting Match as,
Anna Haro
anna-haro#mac.com
Hank M. Zakroff
hank-zakroff#mac.com
Here are the way that you can highlight search string from whole string.
Step 1 : Add following method. that is created NSRegularExpression object for you.
- (NSRegularExpression *)regularExpressionWithString:(NSString *)string options:(NSDictionary *)options
{
// Create a regular expression
BOOL isCaseSensitive = [[options objectForKey:kRWSearchCaseSensitiveKey] boolValue];
BOOL isWholeWords = [[options objectForKey:kRWSearchWholeWordsKey] boolValue];
NSError *error = NULL;
NSRegularExpressionOptions regexOptions = isCaseSensitive ? 0 : NSRegularExpressionCaseInsensitive;
NSString *placeholder = isWholeWords ? #"\\b%#\\b" : #"%#";
NSString *pattern = [NSString stringWithFormat:placeholder, string];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:regexOptions error:&error];
if (error)
{
NSLog(#"Couldn't create regex with given string and options");
}
return regex;
}
Step 2 : Here are the code that highlight the find string from whole string.
// 4: Call the convenient method to create a regex for us with the options we have
NSRegularExpression *regex = [self regularExpressionWithString:searchString options:options];
// 5: Find matches
NSArray *matches = [regex matchesInString:visibleText options:NSMatchingProgress range:visibleTextRange];
// 6: Iterate through the matches and highlight them
for (NSTextCheckingResult *match in matches)
{
NSRange matchRange = match.range;
[visibleAttributedText addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:matchRange];
}
Refer for more help
Edit :
Replace
NSString *placeholder = #"\\b%#";
With
NSString *placeholder = isWholeWords ? #"\\b%#\\b" : #"%#";
Hope this help you.
I'm using a simple pattern with NSRegularExpression to delimit content within a string:
(\s)+(and|or)(\s)+
So, when I use matchesInString it's not the matches that I'm interested in, but the other stuff.
Below is the code that I'm using. Iterating over the matches and then using indexes and lengths to pull out the content.
Question: I'm just wondering if I'm missing something in the api to get the other bits? Or, is the approach below generally ok?
- (NSArray*)separateText:(NSString*)text
{
NSString* regExPattern = #"(\\s)+(and|or)(\\s)+";
NSError* error = NULL;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regExPattern
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, text.length)];
if (matches.count == 0) {
return #[text];
}
NSInteger itemStartIndex = 0;
NSMutableArray* result = [NSMutableArray new];
for (NSTextCheckingResult* match in matches) {
NSRange matchRange = [match range];
if (!matchRange.location == 0) {
NSInteger matchStartIndex = matchRange.location;
NSInteger length = matchStartIndex - itemStartIndex;
NSString* item = [text substringWithRange:NSMakeRange(itemStartIndex, length)];
if (item.length != 0) {
[result addObject:item];
}
}
itemStartIndex = NSMaxRange(matchRange);
}
if (itemStartIndex != text.length) {
NSInteger length = text.length - itemStartIndex;
NSString* item = [text substringWithRange:NSMakeRange(itemStartIndex, length)];
[result addObject:item];
}
return result;
}
You can capture the string before the and|or with parentheses, and add it to your array with rangeAtIndex.
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(.+?)(\\s+(and|or)\\W+|\\s*$)" options:NSRegularExpressionCaseInsensitive error:&error];
NSMutableArray *phrases = [NSMutableArray array];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange range = [result rangeAtIndex:1];
[phrases addObject:[string substringWithRange:range]];
}];
A couple of minor points about my regex:
I added the |\\s*$ construct to capture the last string after the final and|or. If you don't want that, you can eliminate that.
I replaced the second \\s+ (whitespace) with a \\W+ (non-word characters), in case you encountered something like and|or followed by a comma or something else. You could alternatively look explicitly for ,?\\s+ if the comma was the only non-word character you cared about. It just depends upon the specific business problem you're solving.
You might want to replace the first \\s+ with \\W+, too.
If your string contains newline characters, you might want to use the NSRegularExpressionDotMatchesLineSeparators option when you instantiate the NSRegularExpression.
You could replace all matches of the regex with a template string (e.g. ", " or "," etc) and then separate the string components based on that new delimiter.
NSString *stringToBeMatched = #"Your string to be matched";
NSString *regExPattern = #"(\\s)+(and|or)(\\s)+";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regExPattern
options:NSRegularExpressionCaseInsensitive
error:&error];
if (error) {
// handle error
}
NSString *replacementString = [regex stringByReplacingMatchesInString:stringToBeMatched
options:0
range:NSMakeRange(0, stringToBeMatched.length)
withTemplate:#","];
NSArray *otherItemsInString = [replacementString componentsSeparatedByString:#","];
I have an NSString as:
"<a href='javascript:void(null)' onclick='handleCommandForAnchor(this, 10);return false;'>12321<\/a>"
I need to extract the 12321 near the end of the NSString from it and store.
First I tried
NSString *shipNumHtml=[mValues objectAtIndex:1];
NSInteger htmlLen=[shipNumHtml length];
NSString *shipNum=[[shipNumHtml substringFromIndex:htmlLen-12]substringToIndex:8];
But then I found out that number 12321 can be of variable length.
I can't find a method like java's indexOf() to find the '>' and '<' and then find substring with those indices. All the answers I've found on SO either know what substring to search for or know the location if the substring. Any help?
I don't usually advocate using Regular expressions for parsing HTML contents but it seems a regex matching >(\d+)< would to the job in this simple string.
Here is a simple example:
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#">(\\d+)<"
options:0
error:&error];
// Handle error != nil
NSTextCheckingResult *match = [regex firstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
if (match) {
NSRange matchRange = [match rangeAtIndex:1];
NSString *number = [string substringWithRange:matchRange]
NSLog(#"Number: %#", number);
}
As #HaneTV says, you can use the NSString method rangeOfString to search for substrings. Given that the characters ">" and "<" appear in multiple places in your string, so you might want to take a look at NSRegularExpression and/or NSScanner.
that may help on you a bit, I've just tested:
NSString *_string = #"<a href='javascript:void(null)' onclick='handleCommandForAnchor(this, 10);return false;'>12321</a>";
NSError *_error;
NSRegularExpression *_regExp = [NSRegularExpression regularExpressionWithPattern:#">(.*)<" options:NSRegularExpressionCaseInsensitive error:&_error];
NSArray *_matchesInString = [_regExp matchesInString:_string options:NSMatchingReportCompletion range:NSMakeRange(0, _string.length)];
[_matchesInString enumerateObjectsUsingBlock:^(NSTextCheckingResult * result, NSUInteger idx, BOOL *stop) {
for (int i = 0; i < result.numberOfRanges; i++) {
NSString *_match = [_string substringWithRange:[result rangeAtIndex:i]];
NSLog(#"%#", _match);
}
}];
The method should return TRUE if the NSString is something like #"{A5B8A206-E14D-429B-BEB0-2DD0575F3BC0}" and FALSE for a NSString like #"bla bla bla"
I am using something like:
- (BOOL)isValidGUID {
NSError *error;
NSRange range = [[NSRegularExpression regularExpressionWithPattern:#"(?:(\\()|(\\{))?\\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-Z0-9]{12}\\b(?(1)\\))(?(2)\\})" options:NSRegularExpressionCaseInsensitive error:&error] rangeOfFirstMatchInString:self.GUID options:0 range:NSMakeRange(0, [self.GUID length])];
if (self.GUID && range.location != NSNotFound && [self.GUID length] == 38) {
return TRUE;
} else {
return NO;
}
}
but it is not working as I have expected.
Important: GUID which I am using is enclosed by curly braces like this: {A5B8A206-E14D-429B-BEB0-2DD0575F3BC0}
This function will do the job..
-(BOOL)isValidUUID : (NSString *)UUIDString
{
return (bool)[[NSUUID alloc] initWithUUIDString:UUIDString];
}
Thanks #Erzékiel
This regex matches for me
\A\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\}\Z
In short:
\A and \Z is the beginning and end of the string
\{ and \} is escaped curly bracets
[A-F0-9]{8} is exactly 8 characters of either 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
As an NSRegularExpression it would look like this
NSError *error = NULL;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:#"\\A\\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\\}\\Z"
options:NSRegularExpressionAnchorsMatchLines
error:&error];
// use the regex to match the string ...
You can use the following method to check this:
- (BOOL)isUUID:(NSString *)inputStr
{
BOOL isUUID = FALSE;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" options:NSRegularExpressionCaseInsensitive error:nil];
NSInteger matches = [regex numberOfMatchesInString:inputStr options:0 range:NSMakeRange(0, [inputStr length])];
if(matches == 1)
{
isUUID = TRUE;
}
return isUUID;
}
Consider the shortened UUID format. Use code below:
-(BOOL)isValidUUID:(NSString*)uuidString{
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString];
if (uuid ) {
return YES;
}
NSError *error;
NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:#"[^0-9|^a-f]" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [reg matchesInString:uuidString options:NSMatchingReportCompletion range:NSMakeRange(0, uuidString.length)];
if (matches.count == 0 && (uuidString.length == 4 || uuidString.length ==8) ) {
return YES;
}else{
return NO;
}
}