Получение захваченный подтекста с NSRegularExpression
не так просто.
Прежде всего, результат matches(in:range:)
является [NSTextCheckingResult]
, и каждый NSTextCheckingResult
не соответствует в кортеже, как (first?, second)
.
Если вы хотите получить захваченный подтекст, вам необходимо получить диапазон от NSTextCheckingResult
с помощью метода rangeAt(_:)
. rangeAt(0)
представляет диапазон, соответствующий всему рисунку, rangeAt(1)
для первого захвата, rangeAt(2)
для второго и так далее.
И rangeAt(_:)
возвращает NSRange
, а не Swift Range
. Содержание (location
и length
) основано на представлении UTF-16 от NSString
.
И это самая важная часть для вашей цели, rangeAt(_:)
возвращает NSRange(location: NSNotFound, length: 0)
для каждого недостающего захвата.
Таким образом, вам может понадобиться, чтобы написать что-то вроде этого:
let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = try! NSRegularExpression(pattern: "(?:(foo).*)?(bar)") //please find a better example...
for match in regex.matches(in: text1, range: NSRange(0..<text1.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text1 as NSString).substring(with: firstRange) : nil
let second = (text1 as NSString).substring(with: secondRange)
print(first) // Optioonal("foo")
print(second) // bar
}
for match in regex.matches(in: text2, range: NSRange(0..<text2.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text2 as NSString).substring(with: firstRange) : nil
let second = (text2 as NSString).substring(with: secondRange)
print(first) // nil
print(second) // bar
}