Swift 正则表达式
正则表达式是一种强大的文本处理工具,它能够以一定的规则匹配一些特定的字符、字符串等。在 Swift 中,我们可以使用正则表达式来处理各种文本场景,比如字符串匹配、替换、验证等功能。本文将深入介绍 Swift 中的正则表达式相关内容。
基础概念
正则表达式是由特殊字符和普通字符组成的字符序列,它定义了一些特定的规则,用于匹配目标字符串中的模式。例如,我们可以使用正则表达式来匹配一个 email 地址:
let emailPattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let emailRegex = try! NSRegularExpression(pattern: emailPattern)
let email = "example@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
let isMatched = emailRegex.firstMatch(in: email, options: [], range: range) != nil
print(isMatched) // true
在上面的代码中,我们使用了一个正则表达式来定义 email 地址的形式,然后使用 NSRegularExpression 类来编译正则表达式,并创建一个 email 字符串和一个匹配规则范围 range。最后,我们通过调用 firstMatch(in:options:range:) 方法来进行匹配,并判断是否匹配成功。
上面的 email 正则表达式需要分析一下:
- [A-Za-z0-9._%+-]+@:匹配至少一个大小写字母、数字、半角点、下划线、百分号、加号或减号,接着匹配一个半角 @ 符号。
- [A-Za-z0-9.-]+\.:匹配至少一个大小写字母、数字、半角点或减号,接着匹配一个半角点符号。
- [A-Za-z]{2,}:匹配至少两个大小写字母。
其中,“[]”表示字符集合,即匹配方括号中的任意一个字符,“+”表示至少匹配一次,“\”指转义,固定使用“\”。
NSRegularExpression 是系统提供的正则表达式类,它提供了一些接口用于编译正则表达式。在编译正则表达式的时候,NSRegularExpression 会生成一个 Regex 对象,用于处理与之匹配的文本。
接下来我们来详细了解一下正则表达式中的规则。
基本语法
在正则表达式中,我们可以使用普通字符、特殊字符以及元字符等来表达具体的规则。
普通字符:
普通字符指的是键盘上任意可见字符和不可见字符,以及一些转义字符,比如 a-z、A-Z、0-9 等等。
特殊字符:
在正则表达式中,还有一些特殊字符,它们在匹配过程中有着特殊的作用。下面我们列举一下常见的特殊字符:
特殊字符 | 说明 |
---|---|
.* | 匹配任意字符,零个或多个。 |
^ | 匹配字符串开头。 |
$ | 匹配字符串结尾。 |
? | 匹配前面的字符零次或一次。 |
+ | 匹配前面的字符至少一次。 |
\ | 转义字符。 |
| 或操作。 | |
() | 组合多个字符。 |
元字符:
元字符用于表示模式,具体使用方法如下:
元字符 | 说明 |
---|---|
\w | 匹配所有字母、数字、下划线。 |
\d | 匹配所有数字。 |
\s | 匹配所有空格。 |
\b | 匹配单词边界,即单词和空格之间的位置。 |
正则表达式示例
下面是一些示例正则表达式:
- 匹配手机号码:
let phonePattern = "^1[3-9]\\d{9}$"
在上面的表达式中,“^”表示字符串的开始,“$”表示字符串的结束,“\d”表示数字,{9}表示数字出现的次数为 9,[3-9]表示数字的范围在 3-9 之间,”1″ 表示手机号码以 1 开头。
- 匹配IP地址:
let ipPattern = "^([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$"
在上面的表达式中,“^”表示字符串的开始,“$”表示字符串的结束,“\d”表示数字,“[01]?” 表示数字范围在 0-1 之间,? 表示前面的字符匹配零次或一次,“{1,2}” 表示数字出现的次数在 1-2 之间,“|” 表示逻辑或操作,表示与之前的字符组成一个新的匹配项。
- 匹配日期格式:
let datePattern = "^\\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01])$"
在上面的表达式中,“^”表示字符串的开始,“$”表示字符串的结束,“\d”表示数字,“[01]?\d”表示数字在 0-9 之间或者 01-09 之间,“(0?[1-9]|1[0-2])”表示月份可以为 01-12,”(0?[1-9]|[12][0-9]|3[01])” 表示日期可以为 01-31。
正则表达式在 Swift 中的应用
在 Swift 中,我们可以使用 NSRegularExpression 类来编写正则表达式,并进行文本匹配、替换、验证等操作。
NSRegularExpression 类
NSRegularExpression 是系统提供的正则表达式类,它提供了一些接口用于编译正则表达式。在编译正则表达式的时候,NSRegularExpression 会生成一个 Regex 对象,用于处理与之匹配的文本。
下面是 NSRegularExpression 常用属性和方法的介绍:
属性/方法 | 说明 |
---|---|
init(pattern:options:) | 构造函数,用于编译正则表达式。 |
firstMatch(in:options:range:) | 在给定的 range 范围内搜索第一次匹配。 |
matches(in:options:range:) | 在给定的 range 范围内搜索全部匹配。 |
numberOfMatches(in:options:range:) | 搜索给定范围内的匹配次数。 |
stringByReplacingMatches(in:options:range:withTemplate:) | 用给定的模板字符串替换全部匹配字符串。 |
stringByReplacingOccurrences(of:withTemplate:options:range:) | 用给定的模板字符串替换匹配字符串。 |
下面是一个使用 NSRegularExpression 完成正则表达式验证的示例:
let pattern = "^\\d{2}-\\d{2}-\\d{4}$"
let regex = try! NSRegularExpression(pattern: pattern)
let input = "01-01-2022"
let range = NSRange(input.startIndex..<input.endIndex, in: input)
let numberOfMatches = regex.numberOfMatches(in: input, options: [], range: range)
print(numberOfMatches) // 1
NSRegularExpression 的选项
NSRegularExpression 还提供了一些选项,可以控制正则表达式的性能和行为。具体来说,有以下几种常见选项:
选项 | 说明 |
---|---|
caseInsensitive | 忽略字符大小写。 |
allowCommentsAndWhitespace | 忽略正则表达式中的空格和注释。 |
dotMatchesLineSeparators | 允许 . 字符匹配除换行符以外的字符。 |
anchorsMatchLines | 允许 ^ 和 $在换行符之前或之后匹配。 |
useUnixLineSeparators | 把 \n 视为换行符。 |
useUnicodeWordBoundaries | 把 Unicode 的工作方式视为 Boundary(边界),而不是 ASCII 的。 |
我们可以通过以下方式来设置选项:
let regex = try! NSRegularExpression(pattern: pattern, options: [.caseInsensitive,.anchorsMatchLines])
上面的示例代码中,我们设置了忽略字符大小写和允许 ^ 和 $ 在换行符之前或之后匹配的选项。
使用正则表达式进行字符串匹配
正则表达式可以用于字符串的匹配、替换和验证,下面以匹配为例进行介绍。
在使用正则表达式进行字符串匹配时,需要使用 NSRegularExpression 类中的 firstMatch(in:options:range:) 或 matches(in:options:range:) 方法。下面是一个使用正则表达式匹配 email 地址的示例:
let pattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let regex = try! NSRegularExpression(pattern: pattern)
let email = "example@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
let isMatched = regex.firstMatch(in: email, options: [], range: range) != nil
print(isMatched) // true
也可以使用 matches(in:options:range:) 方法查找多个匹配项:
let pattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let regex = try! NSRegularExpression(pattern: pattern)
let email = "example@example.com,example2@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
regex.matches(in: email, options: [], range: range).forEach {
print(email[Range($0.range, in: email)!]) // example@example.com 和 example2@example.com
}
使用正则表达式进行字符串替换
使用正则表达式进行字符串替换时,需要使用 NSRegularExpression 类中的方法 stringByReplacingMatches(in:options:range:withTemplate:) 或 stringByReplacingOccurrences(of:withTemplate:options:range:)。下面是一个使用正则表达式替换 email 地址的示例:
let pattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let regex = try! NSRegularExpression(pattern: pattern)
let email = "example@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
let newEmail = regex.stringByReplacingMatches(in: email, options: [], range: range, withTemplate: "new@example.com")
print(newEmail) // new@example.com
也可以使用 stringByReplacingOccurrences(of:withTemplate:options:range:) 方法替换多个匹配项:
let pattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let regex = try! NSRegularExpression(pattern: pattern)
let email = "example@example.com,example2@example.com"
let range = NSRange(location: 0, length: email.utf16.count)
let newEmail = regex.stringByReplacingOccurrences(of: pattern, withTemplate: "new@example.com", options: [], range: range)
print(newEmail) // new@example.com,new@example.com
使用正则表达式进行字符串验证
使用正则表达式进行字符串验证时,需要使用 NSRegularExpression 类中的 numberOfMatches(in:options:range:) 方法。下面是一个使用正则表达式验证是否为有效的邮政编码的示例:
let pattern = "^\\d{5}$" // 判断是否为5位数字
let regex = try! NSRegularExpression(pattern: pattern)
let zipCode = "12345"
let range = NSRange(location: 0, length: zipCode.utf16.count)
let numberOfMatches = regex.numberOfMatches(in: zipCode, options: [], range: range)
print(numberOfMatches > 0) // true
在上述代码中,我们使用了正则表达式判断是否为 5 位数字,并使用 numberOfMatches(in:options:range:) 方法进行验证。如果返回值大于 0,说明验证成功。
总结
正则表达式是一种强大的文本匹配工具,在 Swift 中,可以使用 NSRegularExpression 类进行编写和使用。在使用正则表达式时,我们需要了解正则表达式的语法和常用字符,以及 NSRegularExpression 类的相关方法和选项。通过掌握这些知识,可以方便地进行文本匹配、替换和验证。