学习 swift 正则表达式(一)

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

正则表达式是一种强大的文本处理工具,可用于在字符串中搜索、匹配和操作特定模式。在 Swift 中,我们可以使用 NSRegularExpression 类来处理正则表达式相关的操作。今天来简单介绍下。

创建正则表达式

在使用正则表达式之前,我们需要先创建一个 NSRegularExpression 实例。这可以通过调用其便利构造器完成,并传入我们想要匹配的模式字符串。

swift 复制代码
let pattern = "^1(3|4|5|6|7|8|9)\\d{9}$"
let phoneNumber1 = "13800138000"
do {
    let regex = try NSRegularExpression(pattern: pattern)
    let range = NSRange(location: 0, length: phoneNumber1.utf16.count)
    print("\(phoneNumber1) 是否为一个手机号: \(regex.firstMatch(in: phoneNumber1, options: [], range: range) != nil)")
    
} catch {
    print("Invalid pattern: \(error.localizedDescription)")
}

在上面的示例中,我们创建了一个用于匹配手机号码格式的正则表达式模式。最终结果打印:13800138000 是否为一个手机号: true

匹配字符串

使用 matches 方法可以检查一个字符串是否与正则表达式模式匹配。该方法返回一个布尔值,比如我们用下边这份代码检测字符串中是否包含手机号。

php 复制代码
let pattern = "1(3|4|5|6|7|8|9)\\d{9}$"
let regex = try! NSRegularExpression(pattern: pattern)
let string = "我的手机号是 13800138000"
let range = NSRange(location: 0, length: string.utf16.count)
let matches = regex.matches(in: string, options: [], range: range)

if matches.isEmpty {
    print("字符串中不包含手机号")
} else {
    print("字符串中包含手机号")
}

查找匹配项

matches(in:options:range:) 方法不仅可以检查字符串是否匹配模式,还可以返回所有匹配项在字符串中的范围。

vbnet 复制代码
let pattern = "1(3|4|5|6|7|8|9)\\d{9}"
let regex = try! NSRegularExpression(pattern: pattern)
let text = "手机号1 14545678901 手机号2 13445558912"
let range = NSRange(location: 0, length: text.utf16.count)

// 查找所有匹配的手机号
let matches = regex.matches(in: text, options: [], range: range)

// 将找到的匹配项转换为String数组
let phoneNumbers = matches.map { match -> String in
    let matchRange = match.range
    if let swiftRange = Range(matchRange, in: text) {
        return String(text[swiftRange])
    }
    return ""
}

print(phoneNumbers.filter { !$0.isEmpty })

输出:

css 复制代码
["14545678901", "13445558912"]

字符串替换

replacingMatches(in:options:range:withTemplate:) 方法允许你用指定的模板字符串替换匹配项。

swift 复制代码
let pattern = "1(3|4|5|6|7|8|9)\\d{9}"
let regex = try! NSRegularExpression(pattern: pattern)
let originalText = "这是我的旧手机号: 13800138000,请更新。"
let range = NSRange(location: 0, length: originalText.utf16.count)
let newPhoneNumber = "13900990099"
let result = regex.stringByReplacingMatches(in: originalText, options: [], range: range, withTemplate: newPhoneNumber)

print("替换后的字符串为:\(result)")

输出:

makefile 复制代码
替换后的字符串为:这是我的旧手机号: 13900990099,请更新。

捕获组

捕获组允许你从匹配项中提取特定的子字符串。在模式中使用括号 () 可以定义捕获组。

ini 复制代码
let text = "我的手机号是14545678901,朋友的手机号是13445558912。"
let pattern = "(1(3|4|5|6|7|8|9)\\d)(\\d{4})(\\d{4})"
let regex = try! NSRegularExpression(pattern: pattern)
let range = NSRange(location: 0, length: text.utf16.count)

let matches = regex.matches(in: text, options: [], range: range)

for match in matches {
    if match.numberOfRanges == 5 { // 匹配到的完整手机号 + 3个捕获组
        let phoneNumberRange = match.range(at: 0) // 完整的手机号
        let prefixRange = match.range(at: 1) // 前三位
        let middleRange = match.range(at: 3) // 中间四位
        let lastRange = match.range(at: 4) // 后四位
        
        if let phoneNumberRange = Range(phoneNumberRange, in: text),
           let prefixRange = Range(prefixRange, in: text),
           let middleRange = Range(middleRange, in: text),
           let lastRange = Range(lastRange, in: text) {
            let phoneNumber = String(text[phoneNumberRange])
            let prefix = String(text[prefixRange])
            let middle = String(text[middleRange])
            let last = String(text[lastRange])
            
            print("手机号: \(phoneNumber), 网络前缀: \(prefix), 中间四位: \(middle), 后四位: \(last)")
        }
    }
}

输出:

yaml 复制代码
手机号: 14545678901, 网络前缀: 145, 中间四位: 4567, 后四位: 8901

手机号: 13445558912, 网络前缀: 134, 中间四位: 4555, 后四位: 8912

匹配选项

NSRegularExpression 提供了几个匹配选项,允许您自定义匹配行为。以下是一些常用的选项:

  • .caseInsensitive: 不区分大小写进行匹配

  • .anchorsMatchLines: 将 ^$ 视为行的开始和结尾

  • .dotMatchesLineSeparators: 允许 . 匹配行分隔符

  • .ignoreMetacharacters: 禁用元字符(如 \?)

常用正则表达式模式

最后,分享一些在实际开发中常用的正则表达式。

  • 电子邮件地址 : ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

  • 网址 : ^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$

  • IP 地址 : ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

  • 十六进制颜色代码 : ^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$

  • 日期 (yyyy-MM-dd) : ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$

  • 时间 (HH:mm:ss) : ^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$

总结

正则表达式是一个强大的工具,可用于执行各种文本处理任务。在 Swift 中,NSRegularExpression 类为我们提供了创建、匹配和操作正则表达式模式的功能。

在 swift 5.7 中,正则表达式的支持进行了升级,这个我们后面有时间再讲。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
开心就好20255 小时前
iOS App 安全加固流程记录,代码、资源与安装包保护
后端·ios
开心就好20256 小时前
iOS App 性能测试工具怎么选?使用克魔助手(Keymob)结合 Instruments 完成
后端·ios
zhongjiahao1 天前
面试常问的 RunLoop,到底在Loop什么?
ios
wvy2 天前
iOS 26手势返回到根页面时TabBar的动效问题
ios
RickeyBoy2 天前
iOS 图片取色完全指南:从像素格式到工程实践
ios
aiopencode3 天前
使用 Ipa Guard 命令行版本将 IPA 混淆接入自动化流程
后端·ios
二流小码农3 天前
鸿蒙开发:路由组件升级,支持页面一键创建
android·ios·harmonyos
iceiceiceice4 天前
iOS PDF阅读器段评实现:如何从 PDFSelection 精准还原一个自然段
前端·人工智能·ios
TT_Close4 天前
【Flutter×鸿蒙】FVM 不认鸿蒙 SDK?4步手动塞进去
flutter·swift·harmonyos
张江4 天前
Swift Concurrency学习
swift