即使
matchesInString()
方法的第一个参数是
String
类型,它在内部使用的仍然是
NSString
。因此,范围参数必须使用
NSString
的长度而不是Swift字符串的长度来提供。否则,针对"扩展字符簇"(例如"flags")可能会失败。
从
Swift 4(Xcode 9)开始,Swift标准库提供了在
Range<String.Index>
和
NSRange
之间进行转换的函数。
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: text,
range: NSRange(text.startIndex..., in: text))
return results.map {
String(text[Range($0.range, in: text)!])
}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例子:
let string = "€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
注意: 强制解包 Range($0.range, in: text)!
是安全的,因为 NSRange
引用了给定字符串 text
的子字符串。但是,如果你想要避免使用强制解包,则可以使用
return results.flatMap {
Range($0.range, in: text).map { String(text[$0]) }
}
所以你应该将给定的Swift字符串转换为 NSString
,然后提取范围。结果将自动转换为Swift字符串数组。
(适用于Swift 1.2的代码可以在编辑历史中找到。)
Swift 2(Xcode 7.3.1):
改为使用NSString
来处理给定的Swift字符串,然后提取范围。结果会自动转换为Swift字符串数组。
func matchesForRegexInText(regex: String, text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matchesInString(text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substringWithRange($0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例子:
let string = "€4€9"
let matches = matchesForRegexInText("[0-9]", text: string)
print(matches)
Swift 3 (Xcode 8)func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let nsString = text as NSString
let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
return results.map { nsString.substring(with: $0.range)}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
例子:
let string = "€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]