Regular Expressions in Objective-C with the NSRegularExpression class

[Questo articolo è disponibile anche in ITALIANO: Espressioni regolari in Objective-C con la classe NSRegularExpression]

In today’s post we see how to use regular expressions in Objective-C. To do this, we create a simple application that reads a text file and looks for all occurrences of a given pattern. For example, suppose you have a file containing the order in which are present, for each order, a line containing the order identifier and its detail lines with the items belonging to the order, with the quantity and price. All orders are listed in sequence and what we want to do is to extrapolate only the lines containing the identifiers of the orders.
An example of our input file could be the following:

 
OrderID:12345 
Item1;3;10:43 
Item2;1;7:20 
Item3;1;8.99 
OrderID:34567 
Item1;1;4:50 
Item2;2;9.99 
OrderID:22873 
Item1;1;10.0 
OrderID:39087 
Item1;2;19.90 

and what we want to obtain is a list of only those rows containing the IDs of the orders. The output of our program should be:

 
OrderID:12345 
OrderID:34567 
OrderID:22873 
OrderID:39087 

We start by defining the pattern that allows us to identify our sequences of interest. The lines that we want to return always contain the string “OrderID:” followed by a numeric code that is the ID of the order. We can then define the regular expression that is right for us in this way: OrderID:\d+
Now save the list of orders as a text file and call it “Orders.txt”. At this point we are ready to proceed. Create in XCode a new OS X project of type “Command Line Tool”, call it TestRegex and select as type “Foundation”. The two images below show these operations:

Regex Output

Once the project is created, we need to edit the main application file, called main.m.
The purpose of our program, as mentioned, is to read a text file and extract, through the use of regular expressions, the strings that interest us. So let’s start by defining the path where our data file is and extract its content, by inserting it into a string object:

 
NSString *fileNameString = @"/Users/Dede/Documents/Orders.txt"; 
         
NSString *stringFromFile = [[NSString alloc] initWithContentsOfFile:fileNameString
                                                           encoding:NSASCIIStringEncoding
                                                              error:&error]; 

Now we have to define our regex, that is the structure of the pattern we want to search and we have already analyzed and identified previously. The class to use for this purpose is NSRegularExpression that can be instantiated with the method initWithPattern that takes as input the regex pattern.

 
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"OrderID:\\d+"
                                                                  options:0 
                                                                    error:nil];

The options parameter can assume different values provided by the NSRegularExpressionOptions enumerator and we will see an example later.
For now we leave the value 0 that represents the default settings.

First, we can see how to return the number of occurrences that match our regex pattern. To do that we call on our NSRegularExpression object the method numberOfMatchesInString, passing to it the string to be searched, the search options and the range of the string in which to search.

 
long n = [regex numberOfMatchesInString:stringFromFile 
                                options:0 
                                  range:NSMakeRange(0, [stringFromFile length])];

In our case we indicated as target string the content of the file we have previously extracted in the string “stringFromFile” and as a search range all its own length (from 0 to the length of the string).

If the number of occurrences found is greater than 0, and then it was found at least one, we retrieve the list of occurrences that match our regex. To do that we use this time the method NSTextCheckingResult objects we can iterate in order to extract, for each element, the entire matched string by the property range.

I report the full program:

 
// 
// Main.m 
// TestRegex 
// 
// Created by Davis Molinari on 19/11/14. 
// Copyright (c) 2014 Davis Molinari. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

int main (int argc, const char *argv[]) 
{ 
    autoreleasepool { 
         
        NSError *error; 
         
        NSString *fileNameString = @"/Users/Dede/Documents/Orders.txt";
          
        NSString *stringFromFile = [[NSString alloc] 
                                    initWithContentsOfFile:fileNameString 
                                    encoding:NSASCIIStringEncoding 
                                    error:&error]; 
         
        NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"OrderID:\\d+"
                                                                          options:0
                                                                            error:nil];
          
        long n = [regex numberOfMatchesInString:stringFromFile 
                                        options:0 
                                          range:NSMakeRange(0, [stringFromFile length])];
          
        NSLog (@"Number of the match: %ld", n); 
         
        if (n> 0) 
        { 
            NSArray *matches = [regex matchesInString:stringFromFile 
                                              options:0 
                                                range:NSMakeRange(0, [stringFromFile length])];
              
            for (NSTextCheckingResult *match in matches) 
            { 
                NSString *matchText = [stringFromFile substringWithRange:[match range]];
                NSLog(@"Found String:%@\n", matchText); 
            } 
        } 
        else 
            NSLog(@"No match found in file %@", fileNameString);        
    } 
    return 0; 
}

Let’s try to run the program, click on the “Build and Run” in Xcode, and see if the result is what we expect.
The generated output is the following:

Regex Program Output
As we can see four occurrences of the pattern “OrderID:” followed by the code of the order have been identified, which is the expected result.

The full Xcode example project can be downloaded here:

One thought on “Regular Expressions in Objective-C with the NSRegularExpression class

  1. Pingback: Espressioni regolari in Objective-C con la classe NSRegularExpression | Dede Blog

Leave a Reply

Your email address will not be published. Required fields are marked *