Récupération sous-texte capturé avec NSRegularExpression
est pas si facile.
Tout d'abord, le résultat de matches(in:range:)
est [NSTextCheckingResult]
, et chaque NSTextCheckingResult
ne correspond pas à tuple comme (first?, second)
.
Si vous souhaitez récupérer un sous-texte capturé, vous devez obtenir la plage de la méthode NSTextCheckingResult
avec rangeAt(_:)
. rangeAt(0)
représente la plage correspondant à l'ensemble du modèle, rangeAt(1)
pour la première capture, rangeAt(2)
pour la seconde, et ainsi de suite.
Et rangeAt(_:)
renvoie NSRange
, pas Swift Range
. Le contenu (location
et length
) est basé sur la représentation UTF-16 de NSString
.
Et ceci est la partie la plus importante pour votre usage, rangeAt(_:)
renvoie NSRange(location: NSNotFound, length: 0)
pour chaque capture manquante.
Ainsi, vous devrez peut-être écrire quelque chose comme ceci:
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
}