shawndreck
shawndreck

Reputation: 2069

NSString regular expression find and replace

Building an iOS app that needs to display some HTML string in a UIWebView object. I am trying to search, find for a pattern and replace with the proper link to an image. The image links are original something like [pic:brand:123], where pic is always pic , brand can be any alphanumeric, and the 123 is can also be any non-whitespace alphanumeric.

So far I have tried a few including:

NSString *pattern = @"\\[pic:([^\\s:\\]]+):([^\\]])\\]";

But none has worked for so far.

Here is a sample code:

NSString *str = @"veryLongHTMLSTRING";
NSLog(@"Original test: %@",[str substringToIndex:500]);
NSError *error = nil;
// use regular expression to replace the emoji
NSRegularExpression *regex = [NSRegularExpression
                                  regularExpressionWithPattern:@"\\[pic:([^\\s:\\]]+):([^\\]])\\]"
                                  options:NSRegularExpressionCaseInsensitive error:&error];
if(error != nil){
    NSLog(@"ERror: %@",error);
}else{
    [regex stringByReplacingMatchesInString:str
                                    options:0
                                      range:NSMakeRange(0, [str length])
                               withTemplate:[NSString stringWithFormat:@"/%@/photo/%@.gif",
                                             IMAGE_BASE_URL, @"$1/$2"]];

NSLog(@"Replaced test: %@",[str substringToIndex:500]);

Upvotes: 1

Views: 7663

Answers (2)

user529758
user529758

Reputation:

You're misunderstanding how the template should be formed. Also, stringByReplacingMatchesInString doesn't alter the original string. Try this (tested):

NSString *target = @"longHTML [pic:whatever:123] longHTMLcontinues";
NSMutableString *s = [target mutableCopy];

NSError *err = nil;
NSRegularExpression *expr = [NSRegularExpression regularExpressionWithPattern:@"\\[pic\\:([a-zA-Z0-9]*)\\:([a-zA-Z0-9]*)\\]" options:0 error:&err];
if (err) {
    NSLog(@"%@", err);
    exit(-1);
}

[expr replaceMatchesInString:s options:0 range:NSMakeRange(0, s.length) withTemplate:@"/photo/$1/$2.gif"];

Upvotes: 2

Martin R
Martin R

Reputation: 540105

I see two errors: There is a + missing in the second capture group of the regex pattern, it should be

NSString *pattern = @"\\[pic:([^\\s:\\]]+):([^\\]]+)\\]";

And stringByReplacingMatchesInString returns a new string, it does not replace the matched string. So you must assign the result to a new string, or use replaceMatchesInString:options:range:withTemplate: with a NSMutableString.

The following modifed code

NSString *pattern = @"\\[pic:([^\\s:\\]]+):([^\\]]+)\\]";
NSString *str = @"bla bla [pic:brand:123] bla bla";
NSLog(@"Original test: %@",str);
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression
                              regularExpressionWithPattern:pattern
                              options:NSRegularExpressionCaseInsensitive error:&error];
if(error != nil){
    NSLog(@"ERror: %@",error);
} else{
    NSString *replaced = [regex stringByReplacingMatchesInString:str
                                    options:0
                                      range:NSMakeRange(0, [str length])
                               withTemplate:[NSString stringWithFormat:@"/%@/photo/%@.gif",
                                             @"IMAGE_BASE_URL", @"$1/$2"]];

    NSLog(@"Replaced test: %@",replaced);
}

produces the output

Original test: bla bla [pic:brand:123] bla bla
Replaced test: bla bla /IMAGE_BASE_URL/photo/brand/123.gif bla bla

Upvotes: 8

Related Questions