【问题标题】:NSRegularExpression: Replace url text with <a> tagsNSRegularExpression:用 <a> 标签替换 url 文本
【发布时间】:2011-05-05 20:21:11
【问题描述】:

我目前正在使用 UIWebView 对来自 twitter 的帖子进行样式化。一些推文当然包含 URL,但不包含 &lt;a&gt; 标签。我可以提取 URL,但是我不确定如何添加 &lt;a&gt; 标签并将其放回推文中。然后,我将在这里使用相同的方法来添加指向@usernames 和#hashtags 的链接。这是我当前代码的示例:

NSString *tweet = @"Sync your files to your Google Docs with a folder on your desktop.  Like Dropbox.  Good choice, Google storage is cheap. http://ow.ly/4OaOo";

NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" options:NSRegularExpressionCaseInsensitive error:NULL];

NSString *match = [tweet substringWithRange:[expression rangeOfFirstMatchInString:tweet options:NSMatchingCompleted range:NSMakeRange(0, [tweet length])]];
NSLog(@"%@", match);// == http://ow.ly/4OaOo

最终,我希望最终的字符串看起来像这样:

Sync your files to your Google Docs with a folder on your desktop. Like Dropbox. Good choice, Google storage is cheap. &lt;a href="http://ow.ly/4OaOo&gt;http://ow.ly/4OaOo&lt;/a&gt;

任何帮助将不胜感激。

【问题讨论】:

    标签: iphone objective-c regex ios


    【解决方案1】:

    这是一个objective-c版本:

    NSString *regexToReplaceRawLinks = @"(\\b(https?):\\/\\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])";   
    
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexToReplaceRawLinks
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    
    NSString *string = @"Sync your files to your Google Docs with a folder on your desktop.  Like Dropbox.  Good choice, Google storage is cheap. http://ow.ly/4OaOo";
    
    NSString *modifiedString = [regex stringByReplacingMatchesInString:string
                                                               options:0
                                                                 range:NSMakeRange(0, [string length])
                                                          withTemplate:@"<a href=\"$1\">$1</a>"];
    
    NSLog(@"%@", modifiedString);
    

    我以前做过类似的事情,但我使用了 javascript 来做。当视图加载完毕后,使用委托方法webViewDidFinishLoad,并注入javascript:

    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        NSString *jsReplaceLinkCode = 
            @"document.body.innerHTML = " 
            @"document.body.innerHTML.replace("
                @"/(\\b(https?):\\/\\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/ig, "
                @"\"<a href='$1'>$1</a>\""
        @");";
    
        [webVew stringByEvaluatingJavaScriptFromString:jsReplaceLinkCode];
    } 
    

    这是非objective-c nsstring引号版本中的javascript调用:

    document.body.innerHTML = document.body.innerHTML.replace(
          /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, 
          "<a href='document.location=$1'>$1</a>"
    );
    

    正则表达式并不完美,但会捕获大部分链接。

    【讨论】:

    • 这会很完美。我什至从未想过使用 Javascript。
    • js 可能会很慢,请查看我的 obj-c 解决方案。
    • 在这种情况下,如果我们使用 regex 两次相同的链接会被添加 link 可以添加另一个
    【解决方案2】:

    您可以使用stringByReplacingOccurrencesOfString:withString: 搜索您的match 并将其替换为HTML 链接。

    NSString *htmlTweet = [tweet stringByReplacingOccurrencesOfString:match withString:html];
    

    (您可能还使用从stringByReplacingCharactersInRange:withString: 中的rangeOfFirstMatchInString:options:range 获得的范围,但我不确定在这种情况下传递一个比范围长度更长的字符串会发生什么) .

    请注意,您的搜索只会找到推文中的第一个链接,如果有多个匹配项,您会错过这些。

    【讨论】:

    • 感谢您的快速回复!您确实有关于仅找到第一个链接的有效观点,并且需要修改我的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    相关资源
    最近更新 更多