一聚教程网:一个值得你收藏的教程网站

热门教程

Swift中利用NSDataDetector提取字符串中所有链接(URL验证)

时间:2022-06-25 23:38:30 编辑:袖梨 来源:一聚教程网

NSDataDetector是继承于NSRegularExpression(Cocoa中的正则表达式)的一个子类,你可以把它看作一个正则表达式匹配器和令人难以置信的复杂的表达式,可以从自然语言(虽然可能更复杂)中提取你想要的信息。

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 由于需要自己写正则表达式,略显麻烦。我们还有个更简单的寻找数据的解决方案:NSDataDetector。

输出结果为:

Match: {9, 14}{http://www.isaced.com}
Match: {30, 14}{(023) 52261439}
可以看到在Block中的NSTextCheckingResult作为结果输出,

注意:当初始化NSDataDetector的时候,只指定自己需要的类型(Type)就可以了,因为多增加一项就会多一些内存的开销。


2,提取出字符串中所有的URL链接


import UIKit
 
class ViewController: UIViewController {
 
    override func viewDidLoad() {
        super.viewDidLoad()
 
        let str = "欢迎访问http://www.111com.net,https://111com.netn以及ftp://111com.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]()
        // 创建一个正则表达式对象
        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.111com.net"
        print(str1)
        print(verifyUrl(str1))
        
        let str2 = "http://www.111com.net"
        print(str2)
        print(verifyUrl(str2))
    }
    
    /**
     验证URL格式是否正确
     */
    private func verifyUrl(str:String) -> Bool {
        // 创建一个正则表达式对象
        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.111com.net"
        print(str1)
        print(verifyUrl(str1))
        
        let str2 = "http://www.111com.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

热门栏目