我想从匹配正则表达式模式的字符串中提取子字符串。
所以我正在寻找这样的东西:
func matchesForRegexInText(regex: String!, text: String!) -> [String] { ??? }
所以这就是我所拥有的:
func matchesForRegexInText(regex: String!, text: String!) -> [String] { var regex = NSRegularExpression(pattern: regex, options: nil, error: nil) var results = regex.matchesInString(text, options: nil, range: NSMakeRange(0, countElements(text))) as Array<NSTextCheckingResult> /// ??? return ... }
问题是,这matchesInString给了我一个数组NSTextCheckingResult,其中NSTextCheckingResult.range是类型NSRange。
matchesInString
NSTextCheckingResult
NSTextCheckingResult.range
NSRange
NSRange不兼容Range<String.Index>,所以它阻止我使用text.substringWithRange(...)
Range<String.Index>
text.substringWithRange(...)
知道如何在没有太多代码行的情况下快速实现这个简单的事情吗?
即使该matchesInString()方法将 aString作为第一个参数,它在内部也可以使用NSString,并且必须使用NSString长度而不是 Swift 字符串长度来给出范围参数。否则对于“扩展字形簇”(例如“标志”)将失败。
matchesInString()
String
NSString
从Swift 4Range<String.Index> (Xcode 9) 开始,Swift 标准库提供了在 和之间转换的函数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。但是,如果您想避免它,请使用
Range($0.range, in: text)!
text
return results.flatMap { Range($0.range, in: text).map { String(text[$0]) } }
反而。
(Swift 3 及更早版本的旧答案:)
因此,您应该将给定的 Swift 字符串转换为 an NSString,然后提取范围。结果将自动转换为 Swift 字符串数组。
(Swift 1.2 的代码可以在编辑历史中找到。)
斯威夫特 2(Xcode 7.3.1):
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) // ["4", "9"]
斯威夫特 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 [] } }