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: <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]()
// 創建一個正則表達式對象
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 {
// 創建一個正則表達式對象
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