Swift中的正则表达式:从基础到高级示例
正则表达式(regex)是一种强大的文本处理工具,可以根据复杂模式搜索、替换和验证字符串。在iOS和macOS的Swift中,正则表达式通过Foundation框架中的NSRegularExpression类实现。本文将解析所有关键方面:从创建最简单的模式到结果处理和性能优化。
本文对刚接触Swift的新手以及希望加深在iOS/macOS应用中文本处理知识的有经验开发者都会有所帮助。
1. NSRegularExpression基础
NSRegularExpression类是Swift中处理正则表达式的主要工具。它提供了在字符串中搜索、替换和提取数据的方法。
1.1. 创建正则表达式
要创建NSRegularExpression对象,需要使用一个初始化器,它接受包含模式的字符串和可选标志(NSRegularExpression.Options)。该构造被包裹在try中,因为如果模式语法不正确,可能会抛出错误。
import Foundation
let pattern = "\\\\d{3}-\\\\d{2}-\\\\d{4}" // 示例:123-45-6789do { let regex = try NSRegularExpression(pattern: pattern, options: []) print("正则表达式创建成功")} catch { print("正则表达式语法错误:\\(error.localizedDescription)")}1.2. 主要选项(NSRegularExpression.Options)
选项允许改变正则表达式的行为。以下是最常用的选项:
.caseInsensitive— 忽略字符大小写(A = a)。.allowCommentsAndWhitespace— 忽略模式中的空格和注释。.dotMatchesLineSeparators— 点(.)也匹配换行符。.anchorsMatchLines— ^和$字符匹配每行的开头和结尾,而不是整个字符串。
使用.caseInsensitive选项的示例:
let pattern = "hello"let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)let testString = "Hello, World!"let range = NSRange(location: 0, length: testString.utf16.count)if regex.firstMatch(in: testString, options: [], range: range) != nil { print("找到匹配项") // 输出:找到匹配项}2. 搜索匹配项和处理结果
创建正则表达式后,可以在字符串中搜索匹配项。为此使用firstMatch和matches方法。
2.1. 搜索第一个匹配项
firstMatch(in:options:range:)方法返回第一个找到的匹配项,作为NSTextCheckingResult对象(如果未找到则返回nil)。
let text = "我的号码:123-45-6789,以及987-65-4321"let pattern = "\\\\d{3}-\\\\d{2}-\\\\d{4}"let regex = try NSRegularExpression(pattern: pattern, options: [])let range = NSRange(location: 0, length: text.utf16.count)
if let match = regex.firstMatch(in: text, options: [], range: range) { let matchedString = (text as NSString).substring(with: match.range) print("第一个匹配项:\\(matchedString)") // 123-45-6789}2.2. 搜索所有匹配项
matches(in:options:range:)方法返回所有匹配项的数组。当需要处理模式的每个出现时,这很有用。
let text = "代码:ABC-123, DEF-456, GHI-789"let pattern = "[A-Z]{3}-\\\\d{3}"let regex = try NSRegularExpression(pattern: pattern, options: [])let range = NSRange(location: 0, length: text.utf16.count)let matches = regex.matches(in: tex