2012-03-06 60 views
12

我在我的iPhone應用上使用以下代碼,取自http://tinyurl.com/remarkablepixels,以從條帶化的.html代碼中提取所有網址。使用NSRegularExpression在iPhone上提取URL

我只能夠提取第一個網址,但我需要一個包含所有網址的的數組。我的NSArray沒有爲每個URL返回NSString,而只是返回對象描述。

如何使我的arrayOfAllMatches以NSStrings的形式返回所有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://mydomain.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}" 
) 

回答

18

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]; 
+0

美麗!像魅力一樣工作!非常感謝jonkroll! – Winston 2012-03-06 16:58:13

+4

工作真棒!是否可以從>之後的標題獲得<<。如果網址是Google,您可以獲得「Google」? – Maximilian 2013-02-18 20:14:42

5

獲得給定字符串的所有鏈接

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); 
} 
+0

沒有優雅的解決方案錯誤:NULL – 2013-11-25 10:20:03

2

我發現自己被這個簡單的操作的複雜性(「匹配所有子」),我做了一個小圖書館我很噁心虛心地致電Unsuck,它以fromallMatches的方式爲NSRegularExpression增加了一些理智。這裏是你如何使用它們:

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

+0

這真是太棒了!感謝您分享您的圖書館,亞歷克斯! – Winston 2013-02-06 14:21:03

13

嘗試NSDataDetector

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

隨着NSDataDetector使用斯威夫特:

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!) 
} 

Using 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!) 
} 

Using 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!) 
} 
+0

夢幻般的答案。所有版本的簡單例子。 +1 – mythicalcoder 2017-01-28 22:14:07

+0

我不認爲你需要這個。因爲您不使用enumerateMatches而導致的reportCompletion選項(在:options:range:using :)中 – marchinram 2017-12-03 21:15:01