整理了一些常用的Swift正則表達(dá)式,包括最新的手機(jī)號(hào)驗(yàn)證,希望對(duì)小伙伴兒們有幫助。
import Foundation
import UIKit
open class Validator {
// MARK: 人臉檢測(cè)
/// 人臉檢測(cè)
/// - Parameter image: 被檢測(cè)圖像
/// - Returns: 是否含有人像
public static func checkFace(_ image: UIImage) -> Bool {
let ciimage = CIImage(cgImage: image.cgImage!)
let detector = CIDetector(ofType: CIDetectorTypeFace,
context: nil,
options: [CIDetectorAccuracy: CIDetectorAccuracyLow])!
let result = detector.features(in: ciimage)
// 識(shí)別出的特征數(shù)量
return result.count > 0 ? true : false
}
// MARK: 通用匹配
/// 通用匹配
/// - Parameters:
/// - input: 匹配的字符串
/// - pattern: 匹配規(guī)則
/// - Returns: 返回匹配的結(jié)果
public static func match(_ input: String, pattern: String) -> Bool {
guard let regex: NSRegularExpression = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else {
return false
}
let matches = regex.matches(in: input,
options: [],
range: NSMakeRange(0, input.utf16.count))
return matches.count > 0
}
// MARK: URL驗(yàn)證
/// URL驗(yàn)證
/// - Parameter string: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
///
/// checkUrl("https://google.com") -> true
///
public static func checkUrl(_ string: String) -> Bool {
return URL(string: string) != nil
}
// MARK: 正則匹配用戶姓名,20位的中文或英文
/// 用戶名驗(yàn)證
/// - Parameter string: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
///
/// checkUserName("張三123") -> true
///
public static func checkUserName(_ string: String) -> Bool {
let regex = "^[a-zA-Z\\u4E00-\\u9FA5]{1,20}"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: string)
}
// MARK: URL Schemed 是否有效
/// URL Schemed 是否有效
/// - Parameter string: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
///
/// checkSchemedUrl("https://google.com") -> true
/// checkSchemedUrl("google.com") -> false
public static func checkSchemedUrl(_ string: String) -> Bool {
guard let url = URL(string: string) else { return false }
return url.scheme != nil
}
// MARK: 郵箱驗(yàn)證
/// 郵箱驗(yàn)證
/// - Parameter email: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
///
/// "john@doe.com".isValidEmail -> true‘
///
public static func checkEmail(_ email: String) -> Bool
{
let regex = "^(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: email)
}
// MARK: 密碼驗(yàn)證
/// 密碼驗(yàn)證
/// - Parameter password: 被校驗(yàn)字符串,8到20位,數(shù)字+小寫(xiě)+大寫(xiě)
/// - Returns: 驗(yàn)證結(jié)果
public static func checkPassword(_ password: String) -> Bool
{
let regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: password)
}
// MARK: 手機(jī)號(hào)驗(yàn)證(????)
/// 手機(jī)號(hào)驗(yàn)證(????)
/// - Parameter phone: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func checkPhone(_ phone: String) -> Bool
{
let regex = "^1[0-9]{10}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: phone)
}
// MARK: 數(shù)字驗(yàn)證
/// 數(shù)字驗(yàn)證
/// - Parameter number: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func checkNumber(_ number: String) -> Bool
{
if number.count == 0 { return false }
let regex = "[0-9]*"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: number)
}
// MARK: 中文驗(yàn)證
/// 中文驗(yàn)證
/// - Parameter number: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func isChinese(_ string: String) -> Bool {
let pattern = "[^\u{4e00}-\u{9fff}]"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return !predicate.evaluate(with: string)
}
// MARK: 字母驗(yàn)證
/// 字母驗(yàn)證
/// - Parameter number: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func isEnglish(_ string: String) -> Bool {
let letters = CharacterSet.letters
return string.rangeOfCharacter(from: letters.inverted) == nil
}
// MARK: 檢查字符串是否包含一個(gè)或多個(gè)字母
/// 檢查字符串是否包含一個(gè)或多個(gè)字母
///
/// checkLetter("123abc") -> true
/// checkLetter("123") -> false
///
public static func checkLetter(_ string: String) -> Bool
{
let regex = "^[A-Za-z0-9]+$"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
return predicate.evaluate(with: string)
}
// MARK: 身份證弱驗(yàn)證
/// 身份證弱驗(yàn)證(????),僅校驗(yàn)格式不驗(yàn)證校驗(yàn)碼
/// - Parameter number: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func checkIdentityCardWeak(_ number: String) -> Bool {
let count = number.count
guard count == 15 || count == 18 else { return false }
// 15位身份證:需全為數(shù)字
if count == 15 {
return number.allSatisfy(\.isNumber)
}
// 18位身份證:前17位需全為數(shù)字
guard number.prefix(17).allSatisfy(\.isNumber) else {
return false
}
// 第18位:數(shù)字或X/x
let lastChar = number.last!
return lastChar.isNumber || lastChar.lowercased() == "x"
}
// MARK: 身份證驗(yàn)證
/// 身份證驗(yàn)證(????)
/// - Parameter number: 被校驗(yàn)字符串
/// - Returns: 驗(yàn)證結(jié)果
public static func checkIdentityCard(_ number: String) -> Bool {
let count = number.count
guard count == 15 || count == 18 else {
return false
}
var carid = number
// 處理15位身份證轉(zhuǎn)換為18位
if count == 15 {
guard number.allSatisfy({ $0.isNumber }) else {
return false
}
var mString = number
mString.insert(contentsOf: "19", at: mString.index(mString.startIndex, offsetBy: 6))
let R = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
let sChecker: [Character] = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
var sum = 0
for i in 0..<17 {
let char = mString[mString.index(mString.startIndex, offsetBy: i)]
sum += Int(String(char))! * R[i]
}
let mod = sum % 11
mString.append(String(sChecker[mod]))
carid = mString
}
// 檢查地區(qū)碼
guard carid.count == 18, areaCodeAt(String(carid.prefix(2))) else {
return false
}
// 提取年月日
let yearStart = carid.index(carid.startIndex, offsetBy: 6)
let year = String(carid[yearStart..<carid.index(yearStart, offsetBy: 4)])
let monthStart = carid.index(yearStart, offsetBy: 4)
let month = String(carid[monthStart..<carid.index(monthStart, offsetBy: 2)])
let dayStart = carid.index(monthStart, offsetBy: 2)
let day = String(carid[dayStart..<carid.index(dayStart, offsetBy: 2)])
// 驗(yàn)證年月日有效性
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
guard let _ = dateFormatter.date(from: "\(year)\(month)\(day)") else {
return false
}
// 檢查前17位均為數(shù)字
let chars = Array(carid)
for i in 0..<17 where !chars[i].isNumber {
return false
}
// 校驗(yàn)碼驗(yàn)證
let R = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
let sChecker: [Character] = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
var sum = 0
for i in 0..<17 {
sum += Int(String(chars[i]))! * R[i]
}
let checkChar = sChecker[sum % 11]
// 允許小寫(xiě)x并轉(zhuǎn)為大寫(xiě)比較
return chars[17].uppercased() == String(checkChar)
}
// 地區(qū)碼驗(yàn)證方法保持不變
public static func areaCodeAt(_ code: String) -> Bool {
let areaCodes: [String: String] = [
"11": "北京", "12": "天津", "13": "河北", "14": "山西", "15": "內(nèi)蒙古",
"21": "遼寧", "22": "吉林", "23": "黑龍江", "31": "上海", "32": "江蘇",
"33": "浙江", "34": "安徽", "35": "福建", "36": "江西", "37": "山東",
"41": "河南", "42": "湖北", "43": "湖南", "44": "廣東", "45": "廣西",
"46": "海南", "50": "重慶", "51": "四川", "52": "貴州", "53": "云南",
"54": "西藏", "61": "陜西", "62": "甘肅", "63": "青海", "64": "寧夏",
"65": "新疆", "71": "臺(tái)灣", "81": "香港", "82": "澳門(mén)", "91": "國(guó)外"
]
return areaCodes[code] != nil
}
}