Swift中的正则表达式:处理文本的强大工具
正则表达式(regex)是iOS和macOS开发者不可或缺的工具。它们允许通过紧凑的模板执行复杂的文本数据搜索、替换和验证。在Swift中,正则表达式的处理通过Foundation框架中的NSRegularExpression类实现。本文将详细讲解在Swift中使用regex的所有方面:从基础语法到高级技术,并附带iOS和macOS应用的实用示例。
Swift中NSRegularExpression的基础
在Swift中处理正则表达式使用NSRegularExpression类。它提供了强大的方法来搜索、替换和从字符串中提取数据。我们来看一下基本的初始化语法:
import Foundation
let pattern = "\\\\d{3}-\\\\d{2}-\\\\d{4}" // SSN的模板let text = "我的SSN: 123-45-6789"
do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { let range = Range(match.range, in: text)! print("找到: \\(text[range])") }} catch { print("正则表达式错误: \\(error.localizedDescription)")}注意Swift字符串中反斜杠的转义。模板中的每个反斜杠都需要写两个(\\\\d代替\\d)。
创建和配置正则表达式
NSRegularExpression的构造函数接受一个可选的options参数,用于配置regex的行为:
.caseInsensitive— 忽略字符大小写.dotMatchesLineSeparators— 点号匹配换行符.anchorsMatchLines— 锚点^和$对每一行生效.useUnixLineSeparators— 仅使用作为行分隔符
let regex = try NSRegularExpression( pattern: "swift", options: [.caseInsensitive])// 现在模板将匹配"Swift"、"SWIFT"、"swift"等使用regex搜索和提取数据
正则表达式的主要任务之一是搜索匹配模板的子字符串。在Swift中,这通过matches(in:options:range:)方法完成。
搜索所有匹配项
let text = "联系方式: email@example.com, support@test.org, admin@site.com"let emailPattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}"
let regex = try NSRegularExpression(pattern: emailPattern)let matches = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
print("找到email数量: \\(matches.count)")for match in matches { if let range = Range(match.range, in: text) { print(String(text[range])) }}// 输出:// 找到email数量: 3// email@example.com// support@test.org// admin@site.com带捕获组的搜索
圆括号中的组允许提取匹配的部分。这对于解析结构化数据特别有用:
let logLine = "2024-01-15 14:30:22 [ERROR] 无法连接到服务器"let logPattern = "(\\\\d{4}-\\\\d{2}-\\\\d{2}) (\\\\d{2}:\\\\d{2}:\\\\d{2}) \\\\[(\\\\w+)\\\\] (.+)"
let regex = try NSRegularExpression(pattern: logPattern)if let match = regex.firstMatch(in: logLine, range: NSRange(logLine.startIndex..., in: logLine)) { let dateRange = Range(match.range(at: 1), in: logLine)! let timeRange = Range(match.range(at: 2), in: logLine)! let levelRange = Range(match.range(at: 3), in: logLine)! let messageRange = Range(match.range(at: 4), in: logLine)! print("日期: \\(logLine[dateRange])") print("时间: \\(logL