Expressions régulières en Swift : un outil puissant pour travailler avec le texte
Les expressions régulières (regex) sont un outil indispensable pour les développeurs iOS et macOS. Elles permettent d'effectuer des recherches complexes, des remplacements et des validations de données textuelles à l'aide de motifs compacts. En Swift, le travail avec les expressions régulières est implémenté via la classe NSRegularExpression du framework Foundation. Dans cet article, nous allons analyser tous les aspects de l'utilisation des regex en Swift : de la syntaxe de base aux techniques avancées, avec des exemples pratiques pour les applications iOS et macOS.
Les bases de NSRegularExpression en Swift
Pour travailler avec les expressions régulières en Swift, on utilise la classe NSRegularExpression. Elle fournit des méthodes puissantes pour rechercher, remplacer et extraire des données à partir de chaînes. Examinons la syntaxe de base d'initialisation :
import Foundation
let pattern = "\\\\d{3}-\\\\d{2}-\\\\d{4}" // Motif pour SSNlet text = "Mon SSN : 123-45-6789"
do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { let range = Range(match.range, in: text)! print("Trouvé : \\(text[range])") }} catch { print("Erreur dans l'expression régulière : \\(error.localizedDescription)")}Notez l'échappement de la barre oblique inverse dans les chaînes Swift. Pour chaque barre oblique inverse dans le motif, il faut en mettre deux (\\\\d au lieu de \\d).
Création et configuration d'une expression régulière
Le constructeur NSRegularExpression accepte un paramètre optionnel options qui permet de configurer le comportement de la regex :
.caseInsensitive— ignorer la casse des caractères.dotMatchesLineSeparators— le point correspond aux caractères de saut de ligne.anchorsMatchLines— les ancres ^ et $ fonctionnent pour chaque ligne.useUnixLineSeparators— utiliser uniquement comme séparateur de ligne
let regex = try NSRegularExpression( pattern: "swift", options: [.caseInsensitive])// Maintenant, le motif trouvera "Swift", "SWIFT", "swift", etc.Recherche et extraction de données avec regex
L'une des tâches principales des expressions régulières est la recherche de sous-chaînes correspondant au motif. En Swift, cela se fait via la méthode matches(in:options:range:).
Recherche de toutes les correspondances
let text = "Contacts : email@example.com, support@test.org, admin@site.com"let emailPattern = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}"
let regex = try NSRegularExpression(pattern: emailPattern)let matches = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
print("Emails trouvés : \\(matches.count)")for match in matches { if let range = Range(match.range, in: text) { print(String(text[range])) }}// Sortie :// Emails trouvés : 3// email@example.com// support@test.org// admin@site.comRecherche avec capture de groupes
Les groupes entre parenthèses permettent d'extraire des parties de la correspondance. C'est particulièrement utile pour l'analyse de données structurées :
let logLine = "2024-01-15 14:30:22 [ERROR] Échec de connexion au serveur"let logPattern = "(\\\\d{4}-\\\\d{2}-\\\\d{2}) (\\\\d{2}:\\\\d{2}:\\\\d{2}) \\\\[(\\\\w+)\\\\] (.+)"
let regex = try NSRegularExpression(pattern: logPattern)if let match = regex.firstMatch(in: logLine, range: NSRange(logLine.startIndex..., in: logLine)) { let dateRange = Range(match.range(at: 1), in: logLine)! let timeRange = Range(match.range(at: 2), in: logLine)! let levelRange = Range(match.range(at: 3), in: logLine)! let messageRange = Range(match.range(at: 4), in: logLine)! print("Date : \\(logLine[dateRange])") print("Heure : \\(logL")