Swift 正则表达式
正则表达式是一种用于匹配字符串模式的工具。Swift 提供了正则表达式的支持,方便开发者在字符串处理中快速进行字符串匹配、查找和替换操作。在本文中,我们将详细介绍 Swift 中的正则表达式。
正则表达式的基本语法
正则表达式是由字符、表达式和运算符组成的字符串。我们以一个简单的例子来说明正则表达式的基本语法:
假设我们要匹配所有的 email 地址,可以使用下面的正则表达式:
^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9\-\.]+)\.([a-zA-Z]{2,5})$
这个正则表达式可以解释为:
- “^”:以什么开头;
- “([a-zA-Z0-9_-.]+)”:匹配由大小写字母、数字、下划线、横线、点“.”组成的字符串;
- “@”:匹配“@”号;
- “([a-zA-Z0-9-.]+)”:匹配同上;
- “.”:匹配“.”号;
- “([a-zA-Z]{2,5})”:匹配由大小写字母组成、长度为2到5位的字符串;
- “$”:以什么结尾。
Swift 中的正则表达式
Swift 中的字符串类型提供了多种方法来处理正则表达式,包括字符串匹配、查找和替换。下面我们逐一介绍。
正则表达式基本使用方法
Swift 中的正则表达式使用 NSRegularExpression
类来实现。
首先,我们需要创建一个正则表达式的实例。在创建实例时,我们需要传入一个正则表达式的字符串,并设置一些选项,如是否区分大小写、是否允许空白字符等。常见选项如下:
let regexOptions: NSRegularExpression.Options = [.caseInsensitive, .allowCommentsAndWhitespace]
然后,我们可以用如下方式创建正则表达式实例:
guard let regex = try? NSRegularExpression(pattern: "^([a-zA-Z0-9_\\-.]+)@([a-zA-Z0-9\\-\\.]+)\\.([a-zA-Z]{2,5})$", options: regexOptions) else {
return
}
接下来,我们可以使用正则表达式实例执行匹配、查找和替换操作。
正则表达式的匹配
在 Swift 中,字符串提供了 range(of:options:range:locale:)
方法来进行匹配。我们可以使用这个方法来查看字符串中是否包含指定的模式。
实例:
let email = "test@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
if let _ = email.range(of: "^([a-zA-Z0-9_\\-.]+)@([a-zA-Z0-9\\-\\.]+)\\.([a-zA-Z]{2,5})$", options: [.regularExpression], range: range, locale: nil) {
print("Matched!")
}
其中,$
字符被用来匹配给定字符串结尾的位置。如果字符串与正则表达式匹配,将打印 “Matched!”。
正则表达式的查找和替换
若要搜索匹配给定模式的字符串,可以使用 enumerateMatches(in:options:range:using:)
方法。该方法会返回一个 NSTextCheckingResult
数组,其中包含查找到的所有字符串范围及其它信息。
实例:
let emails = "test1@example.com, test2@example.com, test3@example.com"
let range = NSRange(location: 0, length: emails.utf16.count)
let regex = try! NSRegularExpression(pattern: "^([a-zA-Z0-9_\\-.]+)@([a-zA-Z0-9\\-\\.]+)\\.([a-zA-Z]{2,5})$", options: [])
regex.enumerateMatches(in: emails, options: [], range: range) { (result, _, _) in
guard let result = result else { return }
let match = (emails as NSString).substring(with: result.range)
print(match)
}
该代码将打印出匹配到的三个 email 地址。
在 Swift 中,我们还可以使用 stringByReplacingMatches(in:options:range:withTemplate:)
方法来进行字符串替换。该方法会使用提供的模板替换所有匹配到的字符串。
实例:
let newEmails = regex.stringByReplacingMatches(in: emails, options: [], range: range, withTemplate: "$1@new.com")
print(newEmails)
该代码将把所有 email 地址的域名替换为 “new.com”。
正则表达式的捕获
在匹配正则表达式时,有时候需要将某些子字符串单独提取出来,可以通过正则表达式的分组捕获功能来实现。
在 Swift 中,我们可以使用 enumerateMatches(in:options:range:using:)
方法来查找所有匹配的字符串,并在回调中访问子字符串的范围。范围将会是 NSTextCheckingResult
类型的对象,其中包含了多个范围,每个范围代表了一个分组。
实例:
let email = "test@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
let regex = try! NSRegularExpression(pattern: "^(.*)@(.*\\..{2,5})$", options: [])
regex.enumerateMatches(in: email, options: [], range: range) { (result, _, _) in
guard let result = result else { return }
print(result.numberOfRanges) // 输出结果为 3,因为正则表达式中有两个分组
let range1 = result.range(at: 1)
let range2 = result.range(at: 2)
let name = (email as NSString).substring(with: range1)
let domain = (email as NSString).substring(with: range2)
print("Name: \(name), Domain: \(domain)")
}
输出结果为:
2
Name: test, Domain: example.com
其中,result.numberOfRanges
获取了所有捕获分组的数量,result.range(at: index)
获取了指定分组的范围。
结论
在 Swift 中,使用正则表达式进行字符串操作非常方便,我们只需将正则表达式字符串传递给相应的方法即可。同时,正则表达式的语法相对简单,但涵盖了大多数常用的字符串匹配需求。掌握正则表达式可以让我们更加高效地处理字符串。