Même si la matchesInString()
méthode prend a String
comme premier argument, elle fonctionne en interne avec NSString
, et le paramètre range doit être donné en utilisant la NSString
longueur et non comme la longueur de la chaîne Swift. Sinon, il échouera pour les «clusters de graphèmes étendus» tels que les «indicateurs».
Depuis Swift 4 (Xcode 9), la bibliothèque standard Swift fournit des fonctions pour convertir entre Range<String.Index>
et 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 []
}
}
Exemple:
let string = "🇩🇪€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
Remarque: le dépliage forcé Range($0.range, in: text)!
est sûr car le NSRange
fait référence à une sous-chaîne de la chaîne donnée text
. Cependant, si vous voulez l'éviter, utilisez
return results.flatMap {
Range($0.range, in: text).map { String(text[$0]) }
}
au lieu.
(Ancienne réponse pour Swift 3 et versions antérieures :)
Vous devez donc convertir la chaîne Swift donnée en un NSString
, puis extraire les plages. Le résultat sera automatiquement converti en un tableau de chaînes Swift.
(Le code de Swift 1.2 se trouve dans l'historique des modifications.)
Swift 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 []
}
}
Exemple:
let string = "🇩🇪€4€9"
let matches = matchesForRegexInText("[0-9]", text: string)
print(matches)
// ["4", "9"]
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 []
}
}
Exemple:
let string = "🇩🇪€4€9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]