Clement Prem
Clement Prem

Reputation: 3119

Regex in objective C

I want to extract only the names from the following string

bob!33@localhost @clement!17@localhost jack!03@localhost

and create an array [@"bob", @"clement", @"jack"].

I have tried NSString's componentsseparatedbystring: but it didn't work as expected. So I am planning to go for regEx.

  1. How can I extract strings between ranges and add it to an array using regEx in objective C?
  2. The initial string might contain more than 500 names, would it be a performance issue if I manipulate the string using regEx?

Upvotes: 4

Views: 600

Answers (4)

staticVoidMan
staticVoidMan

Reputation: 20234

Or even something as simple as this will do the trick:

NSString *strNames = @"bob!33@localhost @clement!17@localhost jack!03@localhost";

strNames = [[strNames componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]]
                                  componentsJoinedByString:@""];

NSArray *arrNames = [strNames componentsSeparatedByString:@"localhost"];
NSLog(@"%@", arrNames);

Output:

(
    bob,
    clement,
    jack,
    ""
)

NOTE: Ignore the last element index while iterating or whatever

Assumption:

  1. "localhost" always comes between names

I know it ain't so optimized but it's one way to do this

Upvotes: 4

holex
holex

Reputation: 24041

I saw the other solutions and it seemed no one tried to use real regular expressions here, so I created a solution which uses it, maybe you or someone else can use it as a possible idea in the future:

NSString *_names = @"bob!33@localhost @clement!17@localhost jack!03@localhost";
NSError *_error;
NSRegularExpression *_regExp = [NSRegularExpression regularExpressionWithPattern:@" ?@?(.*?)!\\d{2}@localhost" options:NSRegularExpressionCaseInsensitive error:&_error];
NSMutableArray *_namesOnly = [NSMutableArray array];
if (!_error) {
    NSLock *_lock = [[NSLock alloc] init];
    [_regExp enumerateMatchesInString:_names options:NSMatchingReportProgress range:NSMakeRange(0, _names.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
        if (result.numberOfRanges > 1) {
            if ([_lock tryLock]) [_namesOnly addObject:[_names substringWithRange:[result rangeAtIndex:1]]], [_lock unlock];
        }
    }];
} else {
    NSLog(@"error : %@", _error);
}

the result can be logged...

NSLog(@"_namesOnly : %@", _namesOnly);

...and that will be:

_namesOnly : (
    bob,
    clement,
    jack
)

Upvotes: 4

Retro
Retro

Reputation: 4005

NSMutableArray* nameArray = [[NSMutableArray alloc] init];
NSArray* youarArray = [yourString componentsSeparatedByString:@" "];
for(NSString * nString in youarArray) {
   NSArray* splitObj = [nString componentsSeparatedByString:@"!"];
   [nameArray addObject:[splitObj[0]]];
}    
NSLog(@"%@", nameArray);

Upvotes: 5

Janak Nirmal
Janak Nirmal

Reputation: 22726

You can do it without regex as below (Assuming ! sign have uniform pattern in your all words),

NSString *names = @"bob!33@localhost @clement!17@localhost jack!03@localhost";
NSArray *namesarray = [names componentsSeparatedByString:@" "];
NSMutableArray *desiredArray = [[NSMutableArray alloc] initWithCapacity:0];
[namesarray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSRange rangeofsign = [(NSString*)obj rangeOfString:@"!"];
    NSString *extractedName = [(NSString*)obj substringToIndex:rangeofsign.location];
    [desiredArray addObject:extractedName];
}];
NSLog(@"%@",desiredArray);

output of above NSLog would be

(
    bob,
    "@clement",
    jack
)

If you still want to get rid of @ symbol in above string you can always replace special characters in any string, for that check this

If you need further help, you can always leave comment

Upvotes: 5

Related Questions