Abhinav
Abhinav

Reputation: 38142

How can I parse a string to extract numbers with a regular expression using NSRegularExpression?

I am new to regular expressions and have no clue how to work with them. I wanted to create a regex for the below piece of text to fetch the min, avg & max time. I would be using them with NSRegularExpression to fetch the range & then the string.

Can someone please help in creating a regex for the below text.

round-trip min/avg/max/stddev = 3.073/6.010/13.312/2.789 ms

Upvotes: 3

Views: 2771

Answers (3)

AlexChaffee
AlexChaffee

Reputation: 8252

Break it down.

I'm assuming you want to get the numeric values out of that string and toss the rest.

First make a regexp to match a number:

  • \d matches a digit
  • \d* matches zero or more digits
  • \. matches a period
  • (\d*\.\d*) matches zero or more digits, then a period, then zero or more digits

Then turn it into a Cocoa string:

  • @"(\\d*\\.\\d*)"

Then make an NSRegularExpression:

NSError error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d*\\.\\d*)"
    options:NSRegularExpressionCaseInsensitive
    error:&error];

Then get an array with all the matches:

NSArray *matches = [regex matchesInString:string
                              options:0
                                range:NSMakeRange(0, [string length])];

Then pull out the values:

NSString* minText = [string substringWithRange:[matches[0] range]];
NSString* avgText = [string substringWithRange:[matches[1] range]];
// etc.

I leave it as an exercise to convert these strings into floats. :-)


Update: I found myself so nauseated by the complexity of this that I made a little library I am humbly calling Unsuck which adds some sanity to NSRegularExpression in the form of from and allMatches methods. Here's how you'd use them:

NSRegularExpression *number = [NSRegularExpression from: @"(\\d*\\.\\d*)"];
NSArray *matches = [number allMatches:@"3.14/1.23/299.992"];

Please check out the unsuck source code on github and tell me all the things I did wrong :-)

Upvotes: 8

Abhinav
Abhinav

Reputation: 38142

I managed this by using (.*) = (.+?)/(.+?)/(.+?)/(.*)

Upvotes: 0

Mathew
Mathew

Reputation: 1798

I know you want a regex, and they are very handy to learn, but it might be a bit heavier lifting than you need for this situation. With that in mind, I am providing an alternative. I am sure someone else will give you a regex as well.

NSString* str = @"round-trip min/avg/max/stddev = 3.073/6.010/13.312/2.789 ms";

NSString* str2 = [str substringFromIndex:32];

NSArray* components = [str2 componentsSeparatedByString:@"/"];

CGFloat min = [[components objectAtIndex:0] doubleValue];
CGFloat avg = [[components objectAtIndex:1] doubleValue];
CGFloat max = [[components objectAtIndex:2] doubleValue];

NSLog(@"min/avg/max: %f/%f/%f",min,avg,max);

Upvotes: 1

Related Questions