在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 正则表达式工具类 1 import Foundation 2 3 //基于NSRegularExpression api 的正则处理工具类 4 public struct Regex { 5 6 private let regularExpression: NSRegularExpression 7 8 //使用正则表达式进行初始化 9 public init(_ pattern: String, options: Options = []) throws { 10 regularExpression = try NSRegularExpression( 11 pattern: pattern, 12 options: options.toNSRegularExpressionOptions 13 ) 14 } 15 16 //正则匹配验证(true表示匹配成功) 17 public func matches(_ string: String) -> Bool { 18 return firstMatch(in: string) != nil 19 } 20 21 //获取第一个匹配结果 22 public func firstMatch(in string: String) -> Match? { 23 let firstMatch = regularExpression 24 .firstMatch(in: string, options: [], 25 range: NSRange(location: 0, length: string.utf16.count)) 26 .map { Match(result: $0, in: string) } 27 return firstMatch 28 } 29 30 //获取所有的匹配结果 31 public func matches(in string: String) -> [Match] { 32 let matches = regularExpression 33 .matches(in: string, options: [], 34 range: NSRange(location: 0, length: string.utf16.count)) 35 .map { Match(result: $0, in: string) } 36 return matches 37 } 38 39 //正则替换 40 public func replacingMatches(in input: String, with template: String, 41 count: Int? = nil) -> String { 42 var output = input 43 let matches = self.matches(in: input) 44 let rangedMatches = Array(matches[0..<min(matches.count, count ?? .max)]) 45 for match in rangedMatches.reversed() { 46 let replacement = match.string(applyingTemplate: template) 47 output.replaceSubrange(match.range, with: replacement) 48 } 49 50 return output 51 } 52 } 53 54 //正则匹配可选项 55 extension Regex { 56 /// Options 定义了正则表达式匹配时的行为 57 public struct Options: OptionSet { 58 59 //忽略字母 60 public static let ignoreCase = Options(rawValue: 1) 61 62 //忽略元字符 63 public static let ignoreMetacharacters = Options(rawValue: 1 << 1) 64 65 //默认情况下,“^”匹配字符串的开始和结束的“$”匹配字符串,无视任何换行。 66 //使用这个配置,“^”将匹配的每一行的开始,和“$”将匹配的每一行的结束。 67 public static let anchorsMatchLines = Options(rawValue: 1 << 2) 68 69 ///默认情况下,"."匹配除换行符(\n)之外的所有字符。使用这个配置,选项将允许“.”匹配换行符 70 public static let dotMatchesLineSeparators = Options(rawValue: 1 << 3) 71 72 //OptionSet的 raw value 73 public let rawValue: Int 74 75 //将Regex.Options 转换成对应的 NSRegularExpression.Options 76 var toNSRegularExpressionOptions: NSRegularExpression.Options { 77 var options = NSRegularExpression.Options() 78 if contains(.ignoreCase) { options.insert(.caseInsensitive) } 79 if contains(.ignoreMetacharacters) { 80 options.insert(.ignoreMetacharacters) } 81 if contains(.anchorsMatchLines) { options.insert(.anchorsMatchLines) } 82 if contains(.dotMatchesLineSeparators) { 83 options.insert(.dotMatchesLineSeparators) } 84 return options 85 } 86 87 //OptionSet 初始化 88 public init(rawValue: Int) { 89 self.rawValue = rawValue 90 } 91 } 92 } 93 94 //正则匹配结果 95 extension Regex { 96 // Match 封装有单个匹配结果 97 public class Match: CustomStringConvertible { 98 //匹配的字符串 99 public lazy var string: String = { 100 return String(describing: self.baseString[self.range]) 101 }() 102 103 //匹配的字符范围 104 public lazy var range: Range<String.Index> = { 105 return Range(self.result.range, in: self.baseString)! 106 }() 107 108 //正则表达式中每个捕获组匹配的字符串 109 public lazy var captures: [String?] = { 110 let captureRanges = stride(from: 0, to: result.numberOfRanges, by: 1) 111 .map(result.range) 112 .dropFirst() 113 .map { [unowned self] in 114 Range($0, in: self.baseString) 115 } 116 117 return captureRanges.map { [unowned self] captureRange in 118 if let captureRange = captureRange { 119 return String(describing: self.baseString[captureRange]) 120 } 121 122 return nil 123 } 124 }() 125 126 private let result: NSTextCheckingResult 127 128 private let baseString: String 129 130 //初始化 131 internal init(result: NSTextCheckingResult, in string: String) { 132 precondition( 133 result.regularExpression != nil, 134 "NSTextCheckingResult必需使用正则表达式" 135 ) 136 137 self.result = result 138 self.baseString = string 139 } 140 141 //返回一个新字符串,根据“模板”替换匹配的字符串。 142 public func string(applyingTemplate template: String) -> String { 143 let replacement = result.regularExpression!.replacementString( 144 for: result, 145 in: baseString, 146 offset: 0, 147 template: template 148 ) 149 150 return replacement 151 } 152 153 //信息 154 public var description: String { 155 return "Match<\"\(string)\">" 156 } 157 } 158 } 测试示例:1、验证字符串格式1 //初始化正则工具类 2 let pattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$" 3 let regex = try! Regex(pattern) 4 5 //验证邮箱地址 6 let email = "[email protected]" 7 if regex.matches(email) { 8 print("正确邮箱格式") 9 }else{ 10 print("错误邮箱格式") 11 } 测试结果:
正确邮箱格式 2、提取字符串(1)获取第一个匹配结果 1 //初始化正则工具类 2 let pattern = "([\\u4e00-\\u9fa5]+):([\\d]+)" 3 let regex = try! Regex(pattern) 4 5 //原始字符串 6 let str = "张三:123,李四:456,王五:789" 7 8 //获取第一个匹配对象 9 if let first = regex.firstMatch(in: str) { 10 print("--- 第一个匹配结果 ---") 11 print(first) 12 print("匹配字符串:", first.string) 13 print("捕获组:", first.captures[0]!, first.captures[1]!) 14 print("匹配范围:", first.range) 15 } 测试结果: 1 --- 第一个匹配结果 --- 2 Match<"张三:123"> 3 匹配字符串: 张三:123 4 捕获组: 张三 123 5 匹配范围: Index(_compoundOffset: 0, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1)..<Index(_compoundOffset: 24, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1) (2)获取所有的匹配结果 1 //初始化正则工具类 2 let pattern = "([\\u4e00-\\u9fa5]+):([\\d]+)" 3 let regex = try! Regex(pattern) 4 5 //原始字符串 6 let str = "张三:123,李四:456,王五:789" 7 8 //获取第一个匹配对象 9 for match in regex.matches(in: str) { 10 print("\n--- 匹配结果 ---") 11 print(match) 12 print("匹配字符串:", match.string) 13 print("捕获组:", match.captures[0]!, match.captures[1]!) 14 print("匹配范围:", match.range) 15 } 测试结果: 1 --- 匹配结果 --- 2 Match<"张三:123"> 3 匹配字符串: 张三:123 4 捕获组: 张三 123 5 匹配范围: Index(_compoundOffset: 0, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1)..<Index(_compoundOffset: 24, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1) 6 7 --- 匹配结果 --- 8 Match<"李四:456"> 9 匹配字符串: 李四:456 10 捕获组: 李四 456 11 匹配范围: Index(_compoundOffset: 28, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1)..<Index(_compoundOffset: 52, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1) 12 13 --- 匹配结果 --- 14 Match<"王五:789"> 15 匹配字符串: 王五:789 16 捕获组: 王五 789 17 匹配范围: Index(_compoundOffset: 56, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 1)..<Index(_compoundOffset: 80, _utf8Buffer: Swift._ValidUTF8Buffer<Swift.UInt32>(_biasedBits: 0), _graphemeStrideCache: 0) 3、字符串替换(1)简单的替换 1 //初始化正则工具类 2 let pattern = "([\\u4e00-\\u9fa5]+):([\\d]+)" 3 let regex = try! Regex(pattern) 4 5 //原始字符串 6 let str = "张三:123,李四:456,王五:789" 7 8 //只替换第1个匹配项 9 let out1 = regex.replacingMatches(in: str, with: "***", count: 1) 10 //替换所有匹配项 11 let out2 = regex.replacingMatches(in: str, with: "***") 12 13 //输出结果 14 print("原始的字符串:", str) 15 print("替换第1个匹配项:", out1) 16 print("替换所有匹配项:", out2) 测试结果: 1 原始的字符串: 张三:123,李四:456,王五:789 2 替换第1个匹配项: ***,李四:456,王五:789 3 替换所有匹配项: ***,***,*** (2)捕获组替换 1 //初始化正则工具类 2 let pattern = "([\\u4e00-\\u9fa5]+):([\\d]+)" 3 let regex = try! Regex(pattern) 4 5 //原始字符串 6 let str = "张三:123,李四:456,王五:789" 7 8 //只替换第1个匹配项 9 let out1 = regex.replacingMatches(in: str, with: "$1的电话是$2", count: 1) 10 //替换所有匹配项 11 let out2 = regex.replacingMatches(in: str, with: "$1的电话是$2") 12 13 //输出结果 14 print("原始的字符串:", str) 15 print("替换第1个匹配项:", out1) 16 print("替换所有匹配项:", out2) 测试结果: 1 原始的字符串: 张三:123,李四:456,王五:789 2 替换第1个匹配项: 张三的电话是123,李四:456,王五:789 3 替换所有匹配项: 张三的电话是123,李四的电话是456,王五的电话是789 4、其他常用的正则表达式1 //用户名验证(允许使用小写字母、数字、下滑线、横杠,一共3~16个字符) 2 ^[a-z0-9_-]{3,16}$ 3 4 //Email验证 5 ^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$ 6 7 //手机号码验证:以1开头的11位纯数字串 8 ^1[0-9]{10}$ 9 10 //URL验证 11 ^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$ 12 13 //IP地址验证 14 ^(?:(?: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]?)$ 15 16 //html标签验证 17 ^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$
|
请发表评论