替换NSString中字符串的出现,同时保持原始字符串的大小写

时间:2012-12-18 16:13:15

标签: iphone objective-c ios nsstring

我有一些使用UIWebview显示的本地HTML和CSS。我想结合搜索命中突出显示。

这是我的突出显示方法:

-(void) highlightsSearchTerm:(NSString *)searchTerm
{
    NSString *highlightedSearchTerm = [NSString stringWithFormat:@"<span class='highlight'>%@</span>",searchTerm];

    NSString *highlightedArticle = [article.articleHTML stringByReplacingOccurrencesOfString:searchTerm withString:highlightedSearchTerm options:NSCaseInsensitiveSearch range:NSMakeRange(0, [article.articleHTML length])];

    article.articleHTML = highlightedArticle;
}

这个问题在于它用用户的搜索查询替换了Obama,该搜索查询可能是obama(注意案例)。我希望保留原始文章的内容,同时加入热门突出显示。

我希望有一个更优雅的解决方案,而不是手动查找每个命中词的起始和结束索引,然后分别插入<span class="highlights">和'。

基本上我想要这样的东西:

+ [NSString stringByWrappingExistingString:(NSString *)stringToWrap withString:(NSString *)wrappingString options:NSCaseInsensitiveCompare];

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您可以使用NSRegularExpression执行此操作(直接输入代码,检查错误):

NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:@"Obama" 
                                                                    options:NSRegularExpressionCaseInsensitive
                                                                      error:NULL];
NSString *output = [re stringByReplacingMatchesInString:inputString
                                                options:0
                                                  range:NSMakeRange(0, inputString.length)
                                           withTemplate:@"<span class='highlight'>$0</span>"];

正则表达式搜索字符串@"Obama"在这种情况下很简单,因为您正在寻找文字匹配;选项options:NSRegularExpressionCaseInsensitive使匹配不区分大小写。

虽然该示例使用文字 Obama ,但显然可以动态构造字符串; 然而在这种情况下要小心使用包含正则表达式元字符的字符串,它们将需要转义。

替换模板包含$0,它将替换为匹配的内容(完全,因此保留大小写)。

答案 1 :(得分:2)

这是:

-(void) highlightsSearchTerm:(NSString *)searchTerm
{
    NSString *openSpan = @"<span class='highlight'>";
    NSString *closeSpan = @"</span>";

    NSRange searchRange = NSMakeRange(0, article.articleHTML.length);
    NSRange foundRange;

    NSString *highlightedArticle = article.articleHTML;

    while (searchRange.location < highlightedArticle.length)
    {
        searchRange.length = highlightedArticle.length - searchRange.location;

        foundRange = [highlightedArticle rangeOfString:searchTerm options:NSCaseInsensitiveSearch range:searchRange];

        if (foundRange.location != NSNotFound)
        {
            // found an occurrence of the substring! do stuff here
            searchRange.location = foundRange.location + foundRange.length;

            NSString *casePreservedSearchQuery = [highlightedArticle substringWithRange:foundRange];
            NSString *styledSearchQuery = [NSString stringWithFormat:@"%@%@%@", openSpan, casePreservedSearchQuery, closeSpan];

            highlightedArticle = [highlightedArticle stringByReplacingCharactersInRange:foundRange withString:styledSearchQuery];

            //increase the current location by the length of new string - search query length
            searchRange.location = searchRange.location + [styledSearchQuery length] - [casePreservedSearchQuery length];
        }
        else
        {
            break;
        }
    }

    // no more substring to find
    article.articleHTML = highlightedArticle;
}