I am trying to search for all words with brackets around them in a group of text and change it to italic in iOS. I am using this code to search for brackets in the text:
static inline NSRegularExpression * ParenthesisRegularExpression() {
static NSRegularExpression *_parenthesisRegularExpression = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_parenthesisRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"\\[[^\\(\\)]+\\]" options:NSRegularExpressionCaseInsensitive error:nil];
});
return _parenthesisRegularExpression;
}
I am using this to show me the matches:
NSRange matchRange = [result rangeAtIndex:0];
NSString *matchString = [[self.markerPointInfoDictionary objectForKey:@"long_description"] substringWithRange:matchRange];
NSLog(@"%@", matchString);
But it is returning me all the text from the first [ to the last ] in the group of text. There is a lot brackets in between.
I am using this code to change the text to italic:
-(TTTAttributedLabel*)setItalicTextForLabel:(TTTAttributedLabel*)attributedLabel fontSize:(float)Size
{
[attributedLabel setText:[self.markerPointInfoDictionary objectForKey:@"long_description"] afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString)
{
NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);
NSRegularExpression *regexp = ParenthesisRegularExpression();
UIFont *italicSystemFont = [UIFont italicSystemFontOfSize:Size];
CTFontRef italicFont = CTFontCreateWithName((__bridge CFStringRef)italicSystemFont.fontName, italicSystemFont.pointSize, NULL);
[regexp enumerateMatchesInString:[mutableAttributedString string] options:0 range:stringRange usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange matchRange = [result rangeAtIndex:0];
NSString *matchString = [[self.markerPointInfoDictionary objectForKey:@"long_description"] substringWithRange:matchRange];
NSLog(@"%@", matchString);
if (italicFont) {
[mutableAttributedString removeAttribute:(NSString *)kCTFontAttributeName range:result.range];
[mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)italicFont range:result.range];
CFRelease(italicFont);
NSRange range1 = NSMakeRange (result.range.location, 1);
NSRange range2 = NSMakeRange (result.range.location + result.range.length -2 , 1);
[mutableAttributedString replaceCharactersInRange:range1 withString:@""];
[mutableAttributedString replaceCharactersInRange:range2 withString:@""];
}
}];
return mutableAttributedString;
}];
return attributedLabel;
}
Btw my Text looks like this:
[hello] welcome [world], my [name] is [lakesh]
The results looks like this:
match string is [hello]
match string is [world]
match string is is [lak
then crash..
Need some guidance to show me my mistake.
I haven't thought about the code you are showing, but your regular expression seems to be too greedy:
@"\\[[^\\(\\)]+\\]"
This matches 1-n characters between brackets "[]". The characters are defined by a character class that says "all characters except paranthesis", i.e. except "()".
In other words, your character class also matches bracket characters. The result is that your expression matches everything in between the first "[" and the last "]".
I suggest you try the following regular expression instead:
@"\\[[^\\[\\]]+\\]"
If you don't have nested brackets, you could even simplify it to this:
@"\\[[^\\]]+\\]"
This is a simplified version of your code and the sample input text you provided, but using the regex that I have suggested. In my environment this works perfectly, it prints 4 lines to my debug output window. I don't know what causes your crash, so I suggest you start to simplify your own code step by step until you have found the problem.
NSString* mutableAttributedString = @"[hello] welcome [world], my [name] is [lakesh]";
NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);
NSRegularExpression* regexp = [[NSRegularExpression alloc] initWithPattern:@"\\[[^\\]]+\\]" options:NSRegularExpressionCaseInsensitive error:nil];
[regexp enumerateMatchesInString:mutableAttributedString
options:0
range:stringRange
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
NSRange matchRange = [result rangeAtIndex:0];
NSString* matchString = [mutableAttributedString substringWithRange:matchRange];
NSLog(@"%@", matchString);
}
];
The main differences to your code are:
TTTAttributedLabel
NSMutableAttributedString
self.markerPointInfoDictionary
if (italicFont)
code blockSo your problem should be in one of these areas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With