Tuesday, October 9, 2012

Regular expression in iOS

NSRegularExpression class is very handy when comes to matching patterns and replacing some patterns if they match. Even though Apple provides the reference on NSRegularExpression but still it doesn't has sufficient examples which could be helpful to beginners that's why I thought to share some examples.

1. How to find whether a string is matching particular regular expression.
    I will illustrate this with an example, Email validator. Assume, we want to check whether email  
   entered by user is following certain pattern or not. For this we are creating a regular expression
  @"[A-Z0-9a-z._]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
      |--User Name --|---HostName --| -- Domain---------|
  This regular expression checks for:
  a. Having at least a character before @
  b. Having at least a character between  @ and .(dot)
  c. Domain name should be between 2 to 4 characters.

 Now in objective-C we can use following method to check email validation,


-(BOOL)validateEmail:(NSString *)email {
    NSString * regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject: email];
}

2. How to replace occurrence of a pattern with replacement string in a given text string.
  
   Assume we have some patterns and replacement strings like
    Pattern               Replacement string
    :A                      GOTA
    :B                      GOTB
    :C                      GOTC

    :D                      GOTD
    :E                      GOTE
    :F                      GOTF
    :G                     GOTG



    Text string : @"this is pattern1 :A and this is pattern2 :B and again :A"
    after replacement we want result like this : @"this is pattern1 GOTA  and this is pattern2 GOTB and  
    again GOTA"

   It can be done by following lines of code:


  -(NSString*)replaceStringWithRegularExpression:(NSRegularExpression*)regex dictionary:(NSDictionary*)dict string:(NSString*)string
{
    NSArray  *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
    
    for (NSTextCheckingResult* b in matches) // Loop through matches
    {
        
        NSString* url = [string substringWithRange:b.range]; // get the actual pattern matched
        if([dict valueForKey:url]) // check if value present in dictionary
        {
            string=[string stringByReplacingOccurrencesOfString:url withString:[dict valueForKey:url]];
            return [self replaceStringWithRegularExpression:regex dictionary:dict string:string];
         // using recursion to avoid iteration when text contains same pattern multiple times
        }
    }
    return string;

}

Call above method like this:

 NSDictionary * dict=[[NSDictionary allocinitWithObjectsAndKeys:@"GOTA",@":A"@"GOTB",@":B",@"GOTC",@":C",@"GOTD",@":D",@"GOTE",@":E",@"GOTF",@":F",nil]; //Create dictionary of patters and replacement strings
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@":A|:B|:C|:D|:E|:F" options:0 error:NULL]; //create regular expression 
    NSString *str = @"this is pattern1 :A and this is pattern2 :B and again :A"; //Text string which needs to be replaced    NSString * result=[self replaceStringWithRegularExpression:regex dictionary:dict string:str];    NSLog(@"result:%@",result);