【问题标题】:Replacing occurrences of strings in NSString while maintaining case of original string在保持原始字符串大小写的同时替换 NSString 中出现的字符串
【发布时间】:2012-12-19 01:19:31
【问题描述】:

我有一些使用 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(注意大小写)。我想在保留原始文章的情况下加入热门突出显示。

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

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

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

有什么想法吗?

【问题讨论】:

    标签: iphone objective-c ios nsstring


    【解决方案1】:

    您可以使用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,它将被匹配的内容替换(完全正确,因此保留大小写)。

    【讨论】:

    • 出于好奇,您认为哪种方法“更好”,为什么:您的还是我的?我喜欢我的,因为它远离正则表达式(也许不是远离正则表达式的好理由),但我喜欢你的,因为它很简洁。
    • @TRedman - “更好”有点主观。上面的代码既短又灵活——比如说,如果您需要将所有出现的“green jelly”更改为“jelly(green)”,保留原始代码的大小写,代码也会一样短。框架还有更多优化的空间,例如多个替换与一次替换一个相比。一般来说,如果可以,请使用更高级别的方法;并且仅在 且仅当您遇到性能问题时才进入较低级别。
    【解决方案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;
    }
    

    【讨论】:

    • 你真的救了我,很棒的答案!
    猜你喜欢
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 2013-10-31
    • 2010-09-06
    • 1970-01-01
    • 2011-03-12
    • 2021-03-17
    相关资源
    最近更新 更多