当前位置: 首页 > 工具软件 > Swift Regex > 使用案例 >

Swift - 正则表达式

齐迪
2023-12-01

作为一门先进的编程语言,Swift 可以说吸收了众多其他先进语言的优点。但是有一点却是让人略微失望的,就是Swift 至今还没有在语言层面上支持正则表达式。

原因大概是App开发并不想Perl 或者Ruby 那样的语言需要处理很多文字匹配的问题。Cocoa开发者确实不会特别依赖正则表达式,但是并不排除有使用正则表达式的场景,我们是否能像其他语言一样,使用比如 =~ 这样的符号来进行正则匹配呢?

最容易想到也是最容易实现的当然是自定义 =~这个运算符。在Cocoa中我们可以使用 NSRegularExpression 来做正则匹配,那么我们为他写一个包装也并不是什么太困难的事情。因为做的是字符串匹配,所以 =~ 左右两边都是字符串。我们可以先写一个接受正则表达式的字符串,以此生成NSRegularExpression 对象。然后使用该对象来匹配输入字符串,并返回结果告诉调用者匹配是否成功。一个最简单的实现可能是下面这样的:

struct RegexHelper {
    let regex: NSRegularExpression?
    
    init(_ pattern: String) {
        regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    }
    
    func match(input: String) -> Bool {
        if let matches = regex?.matches(in: input, options: .reportCompletion, range: NSRange(location: 0, length: input.count)) {
            return matches.count > 0
        } else {
            return false
        }
    }
}

在使用的时候,比如我们想要匹配一个邮箱地址,我们可以这样来使用:

let mailPattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
let matcher = RegexHelper(mailPattern)
let maybeMailAddress = "onev@onev.com"
if matcher.match(input: maybeMailAddress) {
    print("有效的邮箱地址")
}

现在我们有了方便的封装,接下来就让我们实现 =~ 吧。这里只给出结果:

precedencegroup RegexPrecedence {
    higherThan: MultiplicationPrecedence
    associativity: none
    assignment: false
}

infix operator =~ : RegexPrecedence

func =~(lhs: String, rhs: String) -> Bool {
    if lhs.first == "^" && lhs.last == "$" {
        return RegexHelper(lhs).match(input: rhs)
    } else {
        return RegexHelper(rhs).match(input: lhs)
    }
}

这下我们就可以使用类似于其他语言的正则匹配的方法了:

let mailPattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
let maybeMailAddress = "onev@onev.com"
        
if mailPattern =~ maybeMailAddress {
    print("有效的邮箱地址")
}

或者

let mailPattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
let maybeMailAddress = "onev@onev.com"
        
if maybeMailAddress =~ mailPattern {
    print("有效的邮箱地址")
}
 类似资料: