+ 我要发布
我发布的 我的标签 发现
浏览器扩展
斑点象@Edge

swift 5.7 开始让正则变得如此简单

# Regex Regex 类型是 iOS 16 新出的一个类型,利用这个类型可以很容易地生成正则表达式: ``` let pat = #"(\d+)"# let reg = try Regex(pat) ``` 这种创建方式和 NSRegularExpression 差不多,你需要将特殊符号用反斜杠标记,使用 try 来捕获异常情况。 为了不出现上面的创建步骤,swift 出了一种使用两个斜杠"/.../"来直接生成 Regex 的方法,以上代码等同于: ``` let reg = /(\d+)/ ``` 通过正则语法糖的方式生成正则表达式时,可以在编译器检查是否有语法错误,同时还有 Xcode 语法突出显示。 例如使用这个表达式可以检测字符串中的名称和数字 ``` let reg = /(\w+)\s+(\d+)/ let ipt = "ABC 123 abc" if let rst = ipt.firstMatch(of: reg) { print(rst.0) // ABC 123 print(rst.1) // ABC print(rst.2) // 123 } ``` 输出的结果是一个元组,第一个值正则表达式匹配的所有内容,第二个值是捕获的第一个子字符串,第三个值是捕获的第二个子字符串,以此类推。 当然页可以用元组命名每个属性的名字 ``` let reg = /(\w+)\s+(\d+)/ let ipt = "ABC 123 abc" if let (matched, name, count) = ipt.firstMatch(of: reg)?.output { print(matched) // ABC 123 print(name) // ABC print(count) // 123 } ``` 还可以在正则表达式里直接命名捕获的变量 ``` let ipt = "ABC 123 abc" let reg = /(?<name>\w+)\s+(?<count>\d+)/ if let match = ipt.firstMatch(of: reg) { print(match.name) // ABC print(match.count) // 123 } ``` # 匹配方式 swift 提供了几种不同的方法,可以用来匹配正则表达式 ``` //首个匹配 ipt.firstMatch(of: regex) //前缀匹配 ipt.prefixMatch(of: regex) //完整匹配 ipt.wholeMatch(of: regex) let l1 = "ABC 123" // 将空格替换成逗号 let l2 = l1.replacing(/\s+/,with:",") // ABC,123 // 去除字母和空格 let l3 = l1.trimmingPrefix(/\w+\s+/) // 123 // 使用空格拆分 let fs = l1.split(separator: /\s+/) // ["ABC","123"] ``` # 正则表达式生成器 swift 还提供了正则表达式构建器 DSL,以更结构化和更高可读性的方法来构建你想要的正则表达式。 首先导入 RegexBuilder 模块 ``` import RegexBuilder ``` 然后构建正则表达式 ``` let reg = Regex { Capture { OneOrMore(.word) // 一个或多个单词 } OneOrMore(.whitespace) // 一个或多个空格 Capture { OneOrMore(.digit) // 一个或多个数字 } } let input = "ABC 123 abc" if let match = input.firstMatch(of: reg) { let s1 = match.1 // ABC let n1 = match.2 // 123 } ``` 有了这套 DSL 构建器之后,正则将会简单很多(当然还是要记住这些规则才行),除了上边用到的 OneOrMore 之外,还有很多可用的语法表达式,以下是一些常用的: + One 精确匹配出现一次 + OneOrMore 匹配出现一次或多次 + ZeroOrMore 匹配出现零次或一次 + Lookahead 仅当其内容在给定位置匹配时才允许匹配继续 + NegativeLookahead 仅当其内容在给定位置不匹配时才允许继续匹配 + Repeat 指定次数的匹配 其中可输入的常用参数有: + .any 与任何元素匹配的字符类 + .anyNonNewline 与任何非换行符元素匹配的字符类 + .digit 任意数字 + .hexDigit 任何十六进制数字 + .word 任何单词字符 + .whitespace 任何空格字符
我的笔记