是否可以使用NSDataDetector检测NSString中包含空格的链接?

时间:2015-06-09 19:48:38

标签: ios objective-c regex nsdatadetector

首先,我无法控制我得到的文字。只是想把它放在那里,所以你知道我无法改变链接。

我尝试使用NSDataDetector查找链接的文字包含以下内容:

<h1>My main item</h1>
<img src="http://www.blah.com/My First Image Here.jpg">
<h2>Some extra data</h2>

我正在使用的检测代码是这样,但它找不到这个链接:

NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];

for (NSTextCheckingResult *match in matches) 
{
   if ([match resultType] == NSTextCheckingTypeLink)
   {
      NSURL *url = [match URL];
      // does some stuff
   }
}

这是Apple的链接检测错误吗?它无法检测到带空格的链接,或者我做错了什么?

有没有人有更可靠的方法来检测链接,无论它们是否有空格或特殊字符或其他内容?

8 个答案:

答案 0 :(得分:4)

我刚收到Apple的回复,提出了我提交的错误:

  

我们认为此问题已在最新的iOS 9测试版中得到解决。   这是预发布的iOS 9更新。

     

有关完整安装,请参阅发行说明   指令。

     

请使用此版本进行测试。如果您还有问题,请   提供可以帮助我们的任何相关日志或信息   调查。

     

iOS 9 https://developer.apple.com/ios/download/

我将测试并让大家知道这是否已通过iOS 9修复。

答案 1 :(得分:0)

您可以使用空格将字符串拆分为多个部分,以便您拥有一个没有空格的字符串数组。然后,您可以将每个字符串提供给数据检测器。

// assume str = <img src="http://www.blah.com/My First Image Here.jpg">
NSArray *components = [str componentsSeparatedByString:@" "];
for (NSString *strWithNoSpace in components) {
    // feed strings into data detector
}

另一种方法是专门查看该HTML标记。不过,这是一个不太通用的解决方案。

// assume that those 3 HTML strings are in a string array called strArray
for (NSString *htmlLine in strArray) {
    if ([[htmlLine substringWithRange:NSMakeRange(0, 8)] isEqualToString:@"<img src"]) {
        // Get the url from the img src tag
        NSString *urlString = [htmlLine substringWithRange:NSMakeRange(10, htmlLine.length - 12)];
    }
}

答案 2 :(得分:0)

我找到了解决问题的非常黑客的方法。如果有人想出一个可以应用于所有网址的更好的解决方案,请执行此操作。

因为我只关心以.jpg结尾的有这个问题的网址,所以我能够找到一种简单的方法来跟踪这个问题。

基本上,我将字符串从基于"http://开始的组件分解为数组。然后我循环遍历该数组,再次查找.jpg">。找到> 1字符串时,内部数组的计数仅为.jpg">。然后我保留我找到的字符串和我用%20替换修复的字符串,并使用它们对原始字符串进行最后的字符串替换。

它并不完美,可能效率低下,但它可以完成我所需要的工作。

- (NSString *)replaceSpacesInJpegURLs:(NSString *)htmlString
{
    NSString *newString = htmlString;

    NSArray *array = [htmlString componentsSeparatedByString:@"\"http://"];
    for (NSString *str in array)
    {
        NSArray *array2 = [str componentsSeparatedByString:@".jpg\""];

        if ([array2 count] > 1)
        {
            NSString *stringToFix = [array2 objectAtIndex:0];
            NSString *fixedString = [stringToFix stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

            newString = [newString stringByReplacingOccurrencesOfString:stringToFix withString:fixedString];
        }
    }

    return newString;
}

答案 3 :(得分:0)

您可以使用NSRegularExpression来修复所有网址,方法是使用简单的正则表达式来检测链接,然后只对空格进行编码(如果您需要更复杂的编码,可以查看CFURLCreateStringByAddingPercentEscapes并且有很多那些例子)。如果您之前没有使用NSRegularExpression,那么唯一可能需要花费一些时间的是如何迭代结果并进行替换,以下代码应该可以解决这个问题:

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"src=\".*\"" options:NSRegularExpressionCaseInsensitive error:&error];
if (!error)
{
    NSInteger offset = 0;
    NSArray *matches = [regex matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];
    for (NSTextCheckingResult *result in matches)
    {
        NSRange resultRange = [result range];
        resultRange.location += offset;

        NSString *match = [regex replacementStringForResult:result inString:myHTML offset:offset template:@"$0"];
        NSString *replacement = [match stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

        myHTML = [myHTML  stringByReplacingCharactersInRange:resultRange withString:replacement];
        offset += ([replacement length] - resultRange.length);
    }
}

答案 4 :(得分:0)

试试这个正则表达式模式: @"<img[^>]+src=(\"|')([^\"']+)(\"|')[^>]*>"使用忽略大小写...匹配索引= 2表示源网址。

javascript中的正则表达式演示:(尝试任何帮助)

<强> Demo

答案 5 :(得分:0)

尝试使用此代码段(我从第一个评论员user3584460获得了正则表达式):

NSError *error = NULL;
NSString *myHTML = @"<http><h1>My main item</h1><img src=\"http://www.blah.com/My First Image Here.jpg\"><h2>Some extra data</h2><img src=\"http://www.bloh.com/My Second Image Here.jpg\"><h3>Some extra data</h3><img src=\"http://www.bluh.com/My Third-Image Here.jpg\"></http>";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"src=[\"'](.+?)[\"'].*?>" options:NSRegularExpressionCaseInsensitive error:&error];

NSArray *arrayOfAllMatches = [regex matchesInString:myHTML options:0 range:NSMakeRange(0, [myHTML length])];

NSTextCheckingResult *match = [regex firstMatchInString:myHTML options:0 range:NSMakeRange(0, myHTML.length)];



for (NSTextCheckingResult *match in arrayOfAllMatches) {
    NSRange  range = [match rangeAtIndex:1];

    NSString* substringForMatch = [myHTML substringWithRange:range];
    NSLog(@"Extracted URL : %@",substringForMatch);

}

在我的日志中,我有:

Extracted URL  : http://www.blah.com/My First Image Here.jpg
Extracted URL  : http://www.bloh.com/My Second Image Here.jpg
Extracted URL  : http://www.bluh.com/My Third-Image Here.jpg

答案 6 :(得分:-1)

您不应该将NSDataDetector与HTML一起使用。它用于解析普通文本(由用户输入),而不是计算机生成的数据(实际上,它有许多启发式方法可以确保它不会检测到可能与用户无关的计算机生成的东西)。 / p>

如果您的字符串是HTML,那么您应该使用HTML解析库。有许多开源工具包可以帮助您实现这一目标。然后只需获取锚点的href属性,或者在文本节点上运行NSDataDetector,以查找未标记的内容,而不会使用标记污染字符串。

答案 7 :(得分:-1)

网址确实不应包含空格。在执行与URL相关的任何操作之前,我会从字符串中删除所有空格,如下所示

// Custom function which cleans up strings ready to be used for URLs
func cleanStringForURL(string: NSString) -> NSString {
    var temp = string
    var clean = string.stringByReplacingOccurrencesOfString(" ", withString: "")
    return clean
}