2014-03-01 27 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可以作爲替代正則表達式來找到你的文字的位置。一旦你有了匹配的位置,你可以提取前後的部分,並建立你的結果字符串。

使用這兩種技術之一,您應該在嘗試在表中顯示結果之前處理字符串並構建結果集。這確保了在滾動時不會進行真正的處理。

如果以前不能這樣做,請在後臺線程上運行它,並將結果返回主線程以更新單元格(如果它仍然可見,請使用索引路徑進行檢查)。