【问题标题】:Using NSRegularExpression to extract URLs on the iPhone在 iPhone 上使用 NSRegularExpression 提取 URL
【发布时间】:2012-03-24 03:40:44
【问题描述】:

我在我的 iPhone 应用程序上使用以下代码,取自 here,以从条纹 .html 代码中提取所有 URL。

我只能提取第一个 URL,但我需要一个包含 所有 URL 的数组。我的 NSArray 没有返回每个 URL 的 NSStrings,而是只返回对象描述。

如何让我的arrayOfAllMatches 以 NSString 形式返回所有 URL?

-(NSArray *)stripOutHttp:(NSString *)httpLine {

// Setup an NSError object to catch any failures
NSError *error = NULL;  

// create the NSRegularExpression object and initialize it with a pattern
// the pattern will match any http or https url, with option case insensitive

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?" options:NSRegularExpressionCaseInsensitive error:&error];

// create an NSRange object using our regex object for the first match in the string httpline
NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:httpLine options:0 range:NSMakeRange(0, [httpLine length])];

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

// check that our NSRange object is not equal to range of NSNotFound
if (!NSEqualRanges(rangeOfFirstMatch, NSMakeRange(NSNotFound, 0))) {
    // Since we know that we found a match, get the substring from the parent string by using our NSRange object

    NSString *substringForFirstMatch = [httpLine substringWithRange:rangeOfFirstMatch];

    NSLog(@"Extracted URL: %@",substringForFirstMatch);
    NSLog(@"All Extracted URLs: %@",arrayOfAllMatches);

    // return all matching url strings
    return arrayOfAllMatches;
}

return NULL;

}

这是我的 NSLog 输出:

Extracted URL: http://example.com/myplayer    
All Extracted URLs: (
    "<NSExtendedRegularExpressionCheckingResult: 0x106ddb0>{728, 53}{<NSRegularExpression: 0x106bc30> http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)? 0x1}",
    "<NSExtendedRegularExpressionCheckingResult: 0x106ddf0>{956, 66}{<NSRegularExpression: 0x106bc30> http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)? 0x1}",
    "<NSExtendedRegularExpressionCheckingResult: 0x106de30>{1046, 63}{<NSRegularExpression: 0x106bc30> http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)? 0x1}",
    "<NSExtendedRegularExpressionCheckingResult: 0x106de70>{1129, 67}{<NSRegularExpression: 0x106bc30> http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)? 0x1}"
)

【问题讨论】:

    标签: objective-c regex nsstring nsarray nsregularexpression


    【解决方案1】:

    NSDataDetector 使用 Swift :

    let types: NSTextCheckingType = .Link
    var error : NSError?
    
    let detector = NSDataDetector(types: types.rawValue, error: &error)        
    var matches = detector!.matchesInString(text, options: nil, range: NSMakeRange(0, count(text)))
    
    for match in matches {
       println(match.URL!)
    }
    

    使用 Swift 2.0:

    let text = "http://www.google.com. http://www.bla.com"
    let types: NSTextCheckingType = .Link
    
    let detector = try? NSDataDetector(types: types.rawValue)
    
    guard let detect = detector else {
       return
    }
    
    let matches = detect.matchesInString(text, options: .ReportCompletion, range: NSMakeRange(0, text.characters.count))
    
    for match in matches {
       print(match.URL!)
    }
    

    使用 Swift 3.0

    let text = "http://www.google.com. http://www.bla.com"
    let types: NSTextCheckingResult.CheckingType = .link
    
    let detector = try? NSDataDetector(types: types.rawValue)
    
    let matches = detector?.matches(in: text, options: .reportCompletion, range: NSMakeRange(0, text.characters.count))
    
    for match in matches! {
       print(match.url!)
    }
    

    【讨论】:

    • 很棒的答案。所有版本的简单示例。 +1
    • 我认为您不需要 . reportCompletion 选项,因为您没有使用 enumerateMatches(in:options:range:using:)
    【解决方案2】:

    试试 NSDataDetector

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

    【讨论】:

      【解决方案3】:

      我发现自己对这个简单操作(“匹配所有子字符串”)的复杂性感到非常恶心,以至于我创建了一个小库,我谦虚地调用Unsuck,它以@987654324 的形式为NSRegularExpression 添加了一些理智@ 和 allMatches 方法。以下是您如何使用它们:

      NSRegularExpression *re = [NSRegularExpression from: @"(?i)\\b(https?://.*)\\b"]; // or whatever your favorite regex is; Hossam's seems pretty good
      NSArray *matches = [re allMatches:httpLine];
      

      check out the unsuck source code on github 告诉我我做错的所有事情:-)

      请注意,(?i) 使其不区分大小写,因此您无需指定 NSRegularExpressionCaseInsensitive

      【讨论】:

      • 太棒了!感谢您分享您的图书馆,Alex!
      【解决方案4】:

      从给定的字符串中获取所有链接

      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 *someString = @"www.facebook.com/link/index.php This is a sample www.google.com of a http://abc.com/efg.php?EFAei687e3EsA sentence with a URL within it.";
      
      NSArray *matches = [expression matchesInString:someString options:NSMatchingCompleted range:NSMakeRange(0, someString.length)];
      for (NSTextCheckingResult *result in matches) {
              NSString *url = [someString substringWithRange:result.range];
              NSLog(@"found url:%@", url);
      }
      

      【讨论】:

        【解决方案5】:

        matchesInString:options:range: 方法返回一个由NSTextCheckingResult 对象组成的数组。您可以使用快速枚举遍历数组,从原始字符串中提取每个匹配项的子字符串,并将子字符串添加到新数组中。

        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?" options:NSRegularExpressionCaseInsensitive error:&error];
        
        NSArray *arrayOfAllMatches = [regex matchesInString:httpLine options:0 range:NSMakeRange(0, [httpLine length])];
        
        NSMutableArray *arrayOfURLs = [[NSMutableArray alloc] init];
        
        for (NSTextCheckingResult *match in arrayOfAllMatches) {    
            NSString* substringForMatch = [httpLine substringWithRange:match.range];
            NSLog(@"Extracted URL: %@",substringForMatch);
        
            [arrayOfURLs addObject:substringForMatch];
        }
        
        // return non-mutable version of the array
        return [NSArray arrayWithArray:arrayOfURLs];
        

        【讨论】:

        • 漂亮!像魅力一样工作!非常感谢 jonkroll!
        • 效果很好!是否可以从>到google.com">Google</a> 你可以得到“谷歌”?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-12
        • 1970-01-01
        • 2012-09-01
        相关资源
        最近更新 更多