Swift中使用replacingOccurrences正则匹配时如何处理每个匹配项
Swift中对正则匹配项做自定义处理后替换的实现方法
直接用replacingOccurrences的字符串替换方式确实没法对匹配项做自定义逻辑处理,得换用NSRegularExpression的API手动遍历匹配结果,逐个处理后替换。
具体实现步骤
- 创建正则表达式实例,处理可能的正则语法错误
- 找出所有符合规则的匹配项范围
- 从后往前处理每个匹配项(避免替换后字符串长度变化影响后续匹配的位置)
- 对每个匹配到的字符串应用自定义处理函数,再替换回原字符串
代码示例
先定义你的自定义处理函数,比如移除所有空格和换行:
func processMatch(_ match: String) -> String { return match.replacingOccurrences(of: "\\s", with: "", options: .regularExpression) }
或者转大写的处理函数:
func processMatch(_ match: String) -> String { return match.uppercased() }
给String写个扩展方法,封装整个替换逻辑:
extension String { func replacingMatches(of pattern: String, with process: (String) -> String) -> String { guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { return self // 正则语法错误时返回原字符串 } let range = NSRange(startIndex..., in: self) var result = self // 从后往前遍历匹配结果,避免替换后位置偏移 for match in regex.matches(in: self, options: [], range: range).reversed() { let matchRange = Range(match.range, in: self)! let matchedString = String(self[matchRange]) let processedString = process(matchedString) result.replaceSubrange(matchRange, with: processedString) } return result } }
用法示例
处理你给出的测试字符串:
let original = "1 2 3 aa x y z bb 1 2 3 aa p q r bb" let processed = original.replacingMatches(of: #"(?s)aa.*?bb"#, with: processMatch) print(processed) // 输出:1 2 3 aaxyzbb 1 2 3 aapqrbb
关键说明
- 用
NSRegularExpression的matches(in:options:range:)能拿到所有匹配项的精确范围 - 必须从后往前替换:如果从前往后处理,前面替换后的字符串长度变化会导致后面的匹配范围失效,从后往前就不会有这个问题
- 正则里的
(?s)是单行模式,让.能匹配换行符,配合.*?非贪婪匹配,和你原来的aa[.\s\S]*?bb效果一致,写法更简洁
内容的提问来源于stack exchange,提问作者Fattie
相关产品推荐
相关产品推荐

