我正在使用NSScanner在大型NSString中查找单词数组,然后使用html标记突出显示它们。基本上我扫描到第一个单词并在那一点插入标签。问题是NSScanner也在查找部分单词。 例如:
如果我扫描@“test”,@“high”,@“try”,它将匹配许多单词的部分。
TEST 测试 更高 试图
有没有一种方法可以将NSScanner设置为仅匹配整个单词? 感谢。
答案 0 :(得分:1)
如果您的目标是iOS 4或更高版本,请查看-enumerateSubstringsInRange:options:usingBlock:
:
NSMutableString *string = [NSMutableString stringWithString:@"test this out testers! higher than high. try, trying, tryst."];
NSString *startTag = @"<b>";
NSString *endTag = @"</b>";
NSSet *wordsToMatch = [NSSet setWithObjects:@"test", @"high", @"try", nil];
[string enumerateSubstringsInRange:(NSRange){ .location = 0, .length = [string length] } options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if ([wordsToMatch containsObject:substring]) {
[string insertString:startTag atIndex:substringRange.location];
[string insertString:endTag atIndex:substringRange.location + substringRange.length + startTag.length];
}
}];
答案 1 :(得分:1)
首先感谢Wevah使用enumerateSubstrings的解决方案,它肯定是一个正确的解决方案。但是,它不如我解决方案所需的那样高效。我目前解决这个问题的方法是根据borrrden的建议使用正则表达式(很好的建议,谢谢)。我在时间分析器工具中分析了所有三种解决方案。
这是我目前的实施。
-(NSString *)getHighlightedString: (NSString *)unhighlightedString: (NSArray *)termsToHighlight
{
NSMutableString *newString = [[NSMutableString alloc] initWithString:unhighlightedString];
NSString *startTag = @"<b><i>";
NSString *endTag = @"</i></b>";
NSMutableString *expression = [[NSMutableString alloc] init];
for (int i =0; i < [termsToHighlight count]; i++)
{
[expression appendString:@"\\b"];
[expression appendString:[termsToHighlight objectAtIndex:i]];
[expression appendString:@"\\b"];
if ([termsToHighlight count] != i + 1)
{
[expression appendString:@"|"];
}
}
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:nil];
NSArray* results = [regex matchesInString:unhighlightedString options:0 range:NSMakeRange(0, [unhighlightedString length])];
for (NSTextCheckingResult* result in [results reverseObjectEnumerator]) {
[newString insertString:endTag atIndex:result.range.location+result.range.length];
[newString insertString:startTag atIndex:result.range.location];
}
return newString;
}
以下是三种不同测试的性能:
所以你可以看到nsscanner很快,在这种情况下不够准确。我愿意放弃使用正则表达式来实现小的性能,以获得准确性。