0

I'm trying to detect any words between asterisks:

NSString *questionString = @"hello *world*";
NSMutableAttributedString *goodText = [[NSMutableAttributedString alloc] initWithString:questionString]; //should turn the word "world" blue

    NSRange range = [questionString rangeOfString:@"\\b\\*(.+?)\\*\\b" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
    if (range.location != NSNotFound) {
        DLog(@"found a word within asterisks - this never happens");
        [goodText addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];
    }

But I never get a positive result. What's wrong with the regex?

Gabriele Petronella
  • 102,227
  • 20
  • 204
  • 227
soleil
  • 11,239
  • 29
  • 102
  • 172

1 Answers1

3
@"\\B\\*([^*]+)\\*\\B"

should achieve what you expect.

You have to use \B in place of \b for word boundaries, as per Difference between \b and \B in regex.

Finally, using [^*]+ matches each pair of asterisks, instead of the outermost only.

For instance, in the string

Hello *world* how *are* you

it will correctly match world and are, instead of world how are.

Another way for achieving the same is using ? which will make the + non-greedy.

@"\\B\\*(.+?)\\*\\B"

Also it's worth noting that rangeOfString:options returns the range of the first match, whereas if you are interested in all the matches you have to use build a NSRegularExpression instance with that pattern and use its matchesInString:options:range: method.

Community
  • 1
  • 1
Gabriele Petronella
  • 102,227
  • 20
  • 204
  • 227
  • This works. But if the string is "hello \*world\* how \*are\* you", "how" also turns blue. – soleil Nov 08 '13 at 05:07
  • No it doesn't. The rest of your code does, since you are using `rangeOfString` which will return the range of the first match. – Gabriele Petronella Nov 08 '13 at 05:15
  • If you want to retrieve all the matches, you have to use the ` matchesInString:options:range:` method of `NSRegularExpression`. – Gabriele Petronella Nov 08 '13 at 05:16
  • Thanks. Any idea how I can remove the asterisks after I do the regex test? I just want to turn the word blue. The asterisks shouldn't be displayed. I can't do stringByReplacingOccurrencesOfString on goodText because it is an NSMutableAttributedString. – soleil Nov 08 '13 at 05:25
  • I'm afraid you will have to break down the string in `NSString` instances, remove the asterisks, and compose the attributed string again. – Gabriele Petronella Nov 08 '13 at 05:28
  • 1
    P.S. in this case `?` doesn't mean "optional", it means "non-greedy" right? – borrrden Nov 08 '13 at 05:37