我想从匹配正则表达式模式的字符串中提取子字符串。
所以我在寻找这样的东西:
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。
NSRange与Range<String不兼容。索引>,它阻止我使用text。substringwithrange(…)
你知道如何在没有太多行代码的情况下实现这个简单的事情吗?
基本电话号码匹配
let phoneNumbers = ["+79990001101", "+7 (800) 000-11-02", "+34 507 574 147 ", "+1-202-555-0118"]
let match: (String) -> String = {
$0.replacingOccurrences(of: #"[^\d+]"#, with: "", options: .regularExpression)
}
print(phoneNumbers.map(match))
// ["+79990001101", "+78000001102", "+34507574147", "+12025550118"]
在Swift 5中返回所有匹配和捕获组的最快方式
extension String {
func match(_ regex: String) -> [[String]] {
let nsString = self as NSString
return (try? NSRegularExpression(pattern: regex, options: []))?.matches(in: self, options: [], range: NSMakeRange(0, nsString.length)).map { match in
(0..<match.numberOfRanges).map { match.range(at: $0).location == NSNotFound ? "" : nsString.substring(with: match.range(at: $0)) }
} ?? []
}
}
返回一个二维字符串数组:
"prefix12suffix fix1su".match("fix([0-9]+)su")
返回……
[["fix12su", "12"], ["fix1su", "1"]]
// First element of sub-array is the match
// All subsequent elements are the capture groups
上面的大多数解决方案只给出完全匹配,结果忽略了捕获组,例如:^\d+\s+(\d+)
为了获得预期的捕获组匹配,你需要(Swift4):
public extension String {
public func capturedGroups(withRegex pattern: String) -> [String] {
var results = [String]()
var regex: NSRegularExpression
do {
regex = try NSRegularExpression(pattern: pattern, options: [])
} catch {
return results
}
let matches = regex.matches(in: self, options: [], range: NSRange(location:0, length: self.count))
guard let match = matches.first else { return results }
let lastRangeIndex = match.numberOfRanges - 1
guard lastRangeIndex >= 1 else { return results }
for i in 1...lastRangeIndex {
let capturedGroupIndex = match.range(at: i)
let matchedString = (self as NSString).substring(with: capturedGroupIndex)
results.append(matchedString)
}
return results
}
}