2011-01-19 3 views
5

この正規表現はWebサイトで見つかりました。そこでは最高のURL検証式だと言われています。 Diego Periniはそれを作成しました。URLを検証するためのNSRegularExpression

私が直面している問題は、objective-Cと一緒に使用して文字列のURLを検出しようとするときです。 NSRegularExpressionAnchorsMatchLinesNSRegularExpressionIgnoreMetacharactersなどのオプションを使用しようとしましたが、まだ運がありません。

Objective-Cの式の形式が正しくありませんか?何か不足していますか?何か案は?

John Gruberの正規表現も試しましたが、いくつかの無効なURLで失敗します。

 Regular Expression         Explanation of expression      

^             match at the beginning 
//Protocol identifier 
(?: 
    (?:https?|ftp         http, https or ftp 
    ):\\/\\/          :// 
)?             optional 
// User:Pass authentication 
(?: 
    ^\\s+           non white spaces, 1 or more times 
    (?: 
     :^\\s*          : non white spaces, 0 or more times, optionally 
    )[email protected]            @ 
)?             optional 
//Private IP Addresses        ?! Means DO NOT MATCH ahead. So do not match any of the following 
(?: 
    (?!10           10               10.0.0.0 - 10.999.999.999 
     (?: 
      \\.\\d{1,3}        . 1 to 3 digits, three times 
     ){3} 
    ) 
    (?!127           127               127.0.0.0 - 127.999.999.999 
     (?: 
      \\.\\d{1,3}        . 1 to 3 digits, three times 
     ){3} 
    ) 
    (?!169\\.254         169.254              169.254.0.0 - 169.254.999.999 
     (?: 
      \\.\\d{1,3}        . 1 to 3 digits, two times 
     ){2} 
    ) 
    (?!192\\.168         192.168              192.168.0.0 - 192.168.999.999 
     (?: 
      \\.\\d{1,3}        . 1 to 3 digits, two times 
     ){2} 
    ) 
    (?!172\\.          172.              172.16.0.0 - 172.31.999.999 
     (?:                            
      1[6-9]         1 followed by any number between 6 and 9 
      |          or 
      2\\d         2 and any digit 
      |          or 
      3[0-1]         3 followed by a 0 or 1 
     ) 
     (?: 
      \\.\\d{1,3}        . 1 to 3 digits, two times 
     ){2} 
    ) 
    //First Octet IPv4        // match these. Any non network or broadcast IPv4 address 
    (?: 
     [1-9]\\d?         any number from 1 to 9 followed by an optional digit  1 - 99 
     |           or 
     1\\d\\d          1 followed by any two digits        100 - 199 
     |           or 
     2[01]\\d         2 followed by any 0 or 1, followed by a digit    200 - 219 
     |           or 
     22[0-3]          22 followed by any number between 0 and 3     220 - 223 
    ) 
    //Second and Third Octet IPv4 
    (?: 
     \\.           . 
     (?: 
      1?\\d{1,2}        optional 1 followed by any 1 or two digits     0 - 199 
      |          or 
      2[0-4]\\d        2 followed by any number between 0 and 4, and any digit  200 - 249 
      |          or 
      25[0-5]         25 followed by any numbers between 0 and 5     250 - 255 
     ) 
    ){2}           two times 
    //Fourth Octet IPv4 
    (?: 
     \\.           . 
     (?: 
      [1-9]\\d?        any number between 1 and 9 followed by an optional digit 1 - 99 
      |          or 
      1\\d\\d         1 followed by any two digits        100 - 199 
      |          or 
      2[0-4]\\d        2 followed by any number between 0 and 4, and any digit  200 - 249 
      |          or 
      25[0-4]         25 followed by any number between 0 and 4     250 - 254 
     ) 
    ) 
    //Host name 
    |            or     
    (?: 
     (?: 
      [a-z\u00a1-\uffff0-9]+-?    any letter, digit or character one or more times with optional - 
     )*           zero or more times 
     [a-z\u00a1-\uffff0-9]+      any letter, digit or character one or more times 
    ) 
    //Domain name 
    (?: 
     \\.           . 
     (?: 
      [a-z\u00a1-\uffff0-9]+-?    any letter, digit or character one or more times with optional - 
     )*           zero or more times 
     [a-z\u00a1-\uffff0-9]+      any letter, digit or character one or more times 
    )*            zero or more times 
    //TLD identifier 
    (?: 
     \\.           . 
     (?: 
      [a-z\u00a1-\uffff]{2,}     any letter, digit or character more than two times 
     ) 
    ) 
) 
//Port number 
(?: 
    :\\d{2,5}          : followed by any digit, two to five times, optionally 
)?    
//Resource path 
(?: 
    \\/[^\\s]*         /followed by an optional non space character, zero or more times 
)?             optional 
$             match at the end 

私は私が次のコードで式を使用していますと言うことを忘れてしまったと思うEDIT :(部分コード)

NSError *error = NULL; 
NSRegularExpression *detector = [NSRegularExpression regularExpressionWithPattern:[self theRegularExpression] options:0 error:&error]; 
NSArray *links = [detector matchesInString:theText options:0 range:NSMakeRange(0, theText.length)]; 

答えて

9
^(?i)(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)[email protected])?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$ 

私が見つけた最良のURL検証正規表現は、私の質問で説明されています。これはすでにObjective-Cで動作するようにフォーマットされています。しかし、NSRegularExpressionでそれを使用すると、アプリがクラッシュするなど、さまざまな問題が発生しました。 RegexKitLiteには問題ありませんでした。サイズ制限か設定されていないフラグか分かりません。

//First I take the string and put every word in an array, then I match every word with the regular expression 
NSArray *splitIntoWordsArray = [textToMatch componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewLineCharacterSet]]; 
NSMutableString *htmlString = [NSMutableString stringWithString:textToMatch]; 
for (NSString *theText in splitIntoWordsArray){ 
    NSEnumerator *matchEnumerator = [theText matchEnumeratorWithRegex:theRegularExpressionString]; 
    for (NSString *temp in matchEnumerator){ 
     [htmlString replaceOccurrencesOfString:temp withString:[NSString stringWithFormat:@"<a href=\"%@\">%@</a>", temp, temp] options:NSLiteralSearch range:NSMakeRange(0, [htmlString length])]; 
    } 
} 
[htmlString replaceOccurrencesOfString:@"\n" withString:@"<br />" options:NSLiteralSearch range:NSMakeRange(0, htmlString.length)]; 
//embed the text on a webView as HTML 
[webView loadHTMLString:[NSString stringWithFormat:embedHTML, [mainFont fontName], [mainFont pointSize], htmlString] baseURL:nil]; 

結果:URLとメールがクリック可能ないくつかの埋め込まれたHTML、とUIWebViewを 私の最終的なコードは次のように見えました。あなたはまた、

NSError *error = NULL; 
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"(?i)(?:(?:https?):\\/\\/)?(?:\\S+(?::\\S*)[email protected])?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?" options:NSRegularExpressionCaseInsensitive error:&error]; 
if (error) 
    NSLog(@"error"); 
NSString *someString = @"This is a sample of a sentence with a URL http://. http://.. http://../ http://? http://?? http://??/ http://# http://-error-.invalid/ http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com within it."; 
NSRange range = [expression rangeOfFirstMatchInString:someString options:NSMatchingCompleted range:NSMakeRange(0, [someString length])]; 
if (!NSEqualRanges(range, NSMakeRange(NSNotFound, 0))){ 
    NSString *match = [someString substringWithRange:range]; 
    NSLog(@"%@", match); 
} 
else { 
    NSLog(@"no match"); 
} 

は、正規表現は時々アプリケーションがハングアップする原因となりますので、私はグルーバーの定期を使用することを決め、将来

で、それは誰かのお役に立てば幸い試すことができますdataDetectorTypes = UIDataDetectorTypeNone

を設定することを忘れないでください。プロトコルなしでURLを認識するように変更された表現、またはwww:

+0

おかげで良い投稿ができました。 – Jhaliya

+0

あなたの更新されたグルーバーコードは良いですが、 "google.com"と一致しません。ただし、 "google.comm"と "google.co.uk"にマッチします。 – mootymoots

+0

正規表現に感謝します。本当に素晴らしい。 –

7

私は何かが足りないのですか?

あなたのためにこれを行うための組み込みのものがありません。便利なオブジェクト、NSDataDetectorがあります。特定のデータタイプ(たとえば、NSTextCheckingTypeLink)を探すためにそれを作成し、-matchesInString:options:range:を求めます。

Here's an earlier answer of mine showing how to use it

+0

あなたの素早い回答はありがとうございます。私はこれまでに試してみましたが、.asia、.infoなどのURLを認識できません。そのURLはhttp://healthyhomes.asiaのように整形式ではないので、これは私が正規の表現。オンラインテスターを使用して、プロトコル部分を含むhealthhomes.asiaまたはinfo.infoを検出します。 – GianPac

+0

www.google.cの場合@Dave DeLongに失敗しました – JAHelia

+0

2017更新:NSDataDetectorをチェックしました。 'info.info'は動作しますが、' healthyhomes.asia'はまだ動作しません。 'www.google.c'は動作します。 'Foundation'の' NSDataDetector'がこのようなURLをサポートしていない場合、Safari(iOSとデスクトップ)が 'healthyhomes.asia'をどのように訪問できるのか考えません。 –

関連する問題