2012-07-08 62 views
2

我正在使用NSScanner在大NSString中查找單詞數組,然後使用html標記高亮顯示它們。基本上我掃描到第一個單詞並在該點插入標籤。問題在於NSScanner也在查找單詞的部分內容。 例如:NSScanner搜索單詞找到單詞的部分

如果我掃描@「test」,@「high」,@「try」,它將匹配多個單詞的部分。

TEST 測試 更高 試圖

是否有一個很好的方法來設置NSScanner僅全字匹配? 謝謝。

+2

我想你會更好地使用正則表達式來解決這個問題。 – borrrden 2012-07-08 01:38:29

+0

Regex FTW !!!!!! – doNotCheckMyBlog 2012-07-08 01:39:28

+0

但如果我有一個問題,只能通過正則表達式解決...不,我現在有兩個問題? ;) – shoe 2012-07-08 01:41:00

回答

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]; 
    } 
}]; 
+0

枚舉時不會修改嗎?用這個函數做這件事是否安全? – borrrden 2012-07-08 02:19:03

+0

「如果將此方法發送給NSMutableString的實例,則只要它位於enclosingRange範圍內,就允許進行變異(刪除,添加或更改)。」 – Wevah 2012-07-08 02:20:34

+0

忽略我,文檔說它是好的:-X – borrrden 2012-07-08 02:20:35

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; 
} 

下面是每個的三個不同的測試表現:

  1. 我原來NSScanner解決方案
    • 測試一個= 14ms的
    • 檢驗雙= 14ms的
    • 測試三= 22毫秒
  2. W EVAH的解決方案
    • 測試一個= 249ms
    • 檢驗雙= 189ms
    • 測試三= 295ms
  3. 我正則表達式解決上述
    • 測試一個= 69ms
    • 檢驗雙= 34ms
    • 測試三= 26ms

所以你可以看到nsscanner很快,在這種情況下不夠準確。我願意放棄正則表達式的小表現來獲得準確性。