2014-03-01 25 views
0

我想搜索字符串中的搜索字词并突出显示字符串中的所有匹配项。搜索NSString并使用省略号显示结果

应该显示搜索词周围的一些文字(...),搜索词应该用粗体字样(NSMutableAttributedString)。

示例:搜索 “文本”

...样品文本喇嘛......更多文本布拉布拉......喇嘛文本布拉布拉...

NSString *haystackString = [[self.searchResults objectAtIndex:indexPath.row] stripHTML]; 
NSString *needleString = self.searchDisplayController.searchBar.text; 
if (!self.searchRegex) { 
    self.searchRegex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"(?:\\S+\\s)?\\S*%@\\S*(?:\\s\\S+)?", needleString] options:(NSRegularExpressionDotMatchesLineSeparators + NSRegularExpressionCaseInsensitive) error:nil]; 
} 
NSArray *matches = [self.searchRegex matchesInString:haystackString options:kNilOptions range:NSMakeRange(0, haystackString.length)]; 
NSMutableString *tempString = [[NSMutableString alloc] init]; 
for (NSTextCheckingResult *match in matches) { 
    [tempString appendString:@"..."]; 
    [tempString appendString:[haystackString substringWithRange:[match rangeAtIndex:0]]]; 
    [tempString appendString:@"..."]; 
} 
if (tempString) { 
    cell.textLabel.text = tempString; 
} 

我当前的代码似乎是缓慢和不支持NSMutableAttributedString呢。有更好的解决方案吗?谢谢!

+0

您是否尝试过使用扫描仪而不是正则表达式? – Wain

+0

我听说NSScanner应该更快,但我不知道如何做到这一点与上面的帖子想要的输出:{点} {前面的字} {空间} {searchterm粗体字} {空间} {word after} {dots} –

回答

0

要使用构造一个AttributedString只是改变你的代码是这样

// Create a reusable attributed string dots and matchStyle dictionary 
NSAttributedString *dots = [[NSAttributedString alloc] initWithString:@"..."]; 
NSDictionary *matchStyle = @{ NSFontAttributeName : [UIFont boldSystemFontOfSize:12]}; 

NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init]; 
for (NSTextCheckingResult *match in matches) 
{ 
    NSString *matchString = [haystackString substringWithRange:[match rangeAtIndex:0]]; 

    [attributedText appendAttributedString:dots]; 
    [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:matchString attributes:matchStyle]]; 
    [attributedText appendAttributedString:dots]; 
} 

if (attributedText.length > 0) 
{ 
    cell.textLabel.attributedText = attributedText; 
} 

最佳, 萨沙

+0

非常感谢。我已经相应地更改了我的代码,还发现了正则表达式中的一个错误(只在范围0处提供匹配),现在它显示得很好。 [链接](http://pastebin.com/uPqFrxk8)。但速度问题仍然存在(代码在configureCell中使用,并且它会断断续续)。文档应用程序(Raeddle)非常顺利地执行此操作。你有关于速度改进的想法吗? –

0

NSScanner可以作为替代正则表达式来找到你的文字的位置。一旦你有了匹配的位置,你可以提取前后的部分,并建立你的结果字符串。

使用这两种技术之一,您应该在尝试在表中显示结果之前处理字符串并构建结果集。这确保了在滚动时不会进行真正的处理。

如果以前不能这样做,请在后台线程上运行它,并将结果返回主线程以更新单元格(如果它仍然可见,请使用索引路径进行检查)。