作為一門先進(jìn)的編程語言,Swift 可以說吸收了眾多其他先進(jìn)語言的優(yōu)點(diǎn),但是有一點(diǎn)卻是讓人略微失望的,就是 Swift 至今為止并沒有在語言層面上支持正則表達(dá)式。
大概是因為其實(shí) app 開發(fā)并不像 Perl 或者 Ruby 那樣的語言需要處理很多文字匹配的問題,Cocoa 開發(fā)者確實(shí)不是特別依賴正則表達(dá)式。但是并不排除有希望使用正則表達(dá)式的場景,我們是否能像其他語言一樣,使用比如 =~ 這樣的符號來進(jìn)行正則匹配呢?
最容易想到也是最容易實(shí)現(xiàn)的當(dāng)然是自定義 =~ 這個運(yùn)算符。在 Cocoa 中我們可以使用 NSRegularExpression 來做正則匹配,那么其實(shí)我們?yōu)樗鼘懸粋€包裝也并不是什么太困難的事情。因為做的是字符串正則匹配,所以 =~ 左右兩邊都是字符串。“我們可以先寫一個接受正則表達(dá)式的字符串,以此生成 NSRegularExpression 對象。然后使用該對象來匹配輸入字符串,并返回結(jié)果告訴調(diào)用者匹配是否成功。一個最簡單的實(shí)現(xiàn)可能是下面這樣的:
struct RegexHelper {
let regex: NSRegularExpression
init(_ pattern: String) throws {
try regex = NSRegularExpression(pattern: pattern,
options: .caseInsensitive)
}
func match(_ input: String) -> Bool {
let matches = regex.matches(in: input,
options: [],
range: NSMakeRange(0, input.count))
return matches.count > 0
}
}
在使用的時候,比如我們想要匹配一個郵箱地址,我們可以這樣來使用:
let mailPattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
let matcher: RegexHelper
do {
matcher = try RegexHelper(mailPattern)
} catch { return }
let maybeMailAddress = "guodunsong@163.com"
if matcher.match(maybeMailAddress) {
print("有效的郵箱地址")
}
現(xiàn)在我們有了方便的封裝,接下來就讓我們實(shí)現(xiàn) =~ 吧。這里只給出結(jié)果了,關(guān)于如何實(shí)現(xiàn)操作符和重載操作符的內(nèi)容,可以參考操作符一節(jié)的內(nèi)容
precedencegroup MatchPrecedence {
associativity: none
higherThan: DefaultPrecedence
}
infix operator =~: MatchPrecedence
func =~(lhs: String, rhs: String) -> Bool {
do {
return try RegexHelper(rhs).match(lhs)
} catch _ {
return false
}
}
這下我們就可以使用類似于其他語言的正則匹配的方法了:
let maybeMailAddress = "guodunsong@163.com"
if maybeMailAddress =~ mailPattern {
print("有效的郵箱地址")
}
// 輸出:
// 有效的郵箱地址
Swift 1.0 版本主要會專注于成為一個非常適合制作 app 的語言,而現(xiàn)在看來 Apple 和 Chris 也有野心將 Swift 帶到更廣闊的平臺去。那時候可能會在語言層面加上正則表達(dá)式的支持,到時候這篇 tip 可能也就沒有意義了,不過我個人還是非常期盼那一天早些到來。