Swift中利用NSDataDetector提取字串中所有連結(URL驗證)

來源:互聯網
上載者:User

NSDataDetector是繼承於NSRegularExpression(Cocoa中的Regex)的一個子類,你可以把它看作一個Regex匹配器和令人難以置信的複雜的運算式,可以從自然語言(雖然可能更複雜)中提取你想要的資訊。

1,NSDataDetector介紹


NSDataDetector 是繼承於 NSRegularExpression 的一個子類。使用的時候只需要指定要匹配的類型(日期、地址、URL等)就可以提取的想要的資訊,而不需要自己再寫複雜的運算式。


NSDataDetector資料檢測器,檢測是否是連結


NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];//建立檢測器,檢測類型是linke(可改成檢測別的)

    NSArray *matches = [detector matchesInString:textString options:0 range:NSMakeRange(0, textString.length)];//檢測字串

    for (NSTextCheckingResult *match in matches) {

        if ([match resultType] == NSTextCheckingTypeLink) {

            NSRange matchRange = [match range];

      //do something 

    }

  }

使用 NSRegularExpression 由於需要自己寫Regex,略顯麻煩。我們還有個更簡單的尋找資料的解決方案:NSDataDetector。

輸出結果為:

Match: <NSLinkCheckingResult: 0x7510b00>{9, 14}{http://www.isaced.com}
Match: <NSPhoneNumberCheckingResult: 0x8517140>{30, 14}{(023) 52261439}
可以看到在Block中的NSTextCheckingResult作為結果輸出,

注意:當初始化NSDataDetector的時候,只指定自己需要的類型(Type)就可以了,因為多增加一項就會多一些記憶體的開銷。


2,提取出字串中所有的URL連結


import UIKit
 
class ViewController: UIViewController {
 
    override func viewDidLoad() {
        super.viewDidLoad()
 
        let str = "歡迎訪問http://www.111cn.net,https://111cn.net\n以及ftp://111cn.net"
        print("測試字串式:\n\(str)\n")
        
        print("匹配到的連結:")
        let urls = getUrls(str)
        for url in urls {
            print(url)
        }
    }
    
    /**
     匹配字串中所有的URL
     */
    private func getUrls(str:String) -> [String] {
        var urls = [String]()
        // 建立一個Regex對象
        do {
            let dataDetector = try NSDataDetector(types:
                NSTextCheckingTypes(NSTextCheckingType.Link.rawValue))
            // 匹配字串,返回結果集
            let res = dataDetector.matchesInString(str,
                options: NSMatchingOptions(rawValue: 0),
                range: NSMakeRange(0, str.characters.count))
            // 取出結果
            for checkingRes in res {
                urls.append((str as NSString).substringWithRange(checkingRes.range))
            }
        }
        catch {
            print(error)
        }
        return urls
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

3,驗證字串是不是一個有效URL連結


import UIKit
 
class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let str1 = "歡迎訪問http://www.111cn.net"
        print(str1)
        print(verifyUrl(str1))
        
        let str2 = "http://www.111cn.net"
        print(str2)
        print(verifyUrl(str2))
    }
    
    /**
     驗證URL格式是否正確
     */
    private func verifyUrl(str:String) -> Bool {
        // 建立一個Regex對象
        do {
            let dataDetector = try NSDataDetector(types:
                NSTextCheckingTypes(NSTextCheckingType.Link.rawValue))
            // 匹配字串,返回結果集
            let res = dataDetector .matchesInString(str,
                options: NSMatchingOptions(rawValue: 0),
                range: NSMakeRange(0, str.characters.count))
            // 判斷結果(完全符合)
            if res.count == 1  && res[0].range.location == 0
                && res[0].range.length == str.characters.count {
                    return true
            }
        }
        catch {
            print(error)
        }
        return false
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

注意:驗證URL連結更簡單的辦法
我們還可以藉助系統提供的 canOpenURL() 方法來檢測一個連結的有效性,比如上面範例可以改成如下的判斷方式:


import UIKit
 
class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let str1 = "歡迎訪問http://www.111cn.net"
        print(str1)
        print(verifyUrl(str1))
        
        let str2 = "http://www.111cn.net"
        print(str2)
        print(verifyUrl(str2))
    }
    
    /**
     驗證URL格式是否正確
     */
    private func verifyUrl(str:String) -> Bool {
        //建立NSURL執行個體
        if let url = NSURL(string: str) {
            //檢測應用是否能開啟這個NSURL執行個體
            return UIApplication.sharedApplication().canOpenURL(url)
        }
        return false
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

看了下NSTextCheckingResult.h檔案,裡面可以找到一些系統為你設定好的匹配類型:

typedef NS_OPTIONS(uint64_t, NSTextCheckingType) {    // a single type
    NSTextCheckingTypeOrthography           = 1ULL << 0,            // language identification
    NSTextCheckingTypeSpelling              = 1ULL << 1,            // spell checking
    NSTextCheckingTypeGrammar               = 1ULL << 2,            // grammar checking
    NSTextCheckingTypeDate                  = 1ULL << 3,            // date/time detection
    NSTextCheckingTypeAddress               = 1ULL << 4,            // address detection
    NSTextCheckingTypeLink                  = 1ULL << 5,            // link detection
    NSTextCheckingTypeQuote                 = 1ULL << 6,            // smart quotes
    NSTextCheckingTypeDash                  = 1ULL << 7,            // smart dashes
    NSTextCheckingTypeReplacement           = 1ULL << 8,            // fixed replacements, such as copyright symbol for (c)
    NSTextCheckingTypeCorrection            = 1ULL << 9,            // autocorrection
    NSTextCheckingTypeRegularExpression NS_ENUM_AVAILABLE(10_7, 4_0)  = 1ULL << 10,           // regular expression matches
    NSTextCheckingTypePhoneNumber NS_ENUM_AVAILABLE(10_7, 4_0)        = 1ULL << 11,           // phone number detection
    NSTextCheckingTypeTransitInformation NS_ENUM_AVAILABLE(10_7, 4_0) = 1ULL << 12            // transit (e.g. flight) info detection
};

當然這裡只是截取了一部分,具體可以點dataDetectorWithTypes方法進入到NSTextCheckingResult.h檔案中查看。

NSTextCheckingTypeDate date
duration
timeZone
NSTextCheckingTypeAddress addressComponents
NSTextCheckingNameKey
NSTextCheckingJobTitleKey
NSTextCheckingOrganizationKey
NSTextCheckingStreetKey
NSTextCheckingCityKey
NSTextCheckingStateKey
NSTextCheckingZIPKey
NSTextCheckingCountryKey
NSTextCheckingPhoneKey
NSTextCheckingTypeLink url
NSTextCheckingTypePhoneNumber phoneNumber
NSTextCheckingTypeTransitInformation components*
NSTextCheckingAirlineKey
NSTextCheckingFlightKey

如果你想在UILabel中簡單地使用NSDataDetector

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.