Expresiones regulares en Swift con ejemplos: en la práctica
Las expresiones regulares (regex) son una herramienta poderosa para trabajar con datos de texto. En Swift, para trabajar con expresiones regulares se utiliza la clase NSRegularExpression del framework Foundation. En este artículo, analizaremos ejemplos prácticos de uso de expresiones regulares en Swift para aplicaciones iOS y macOS: desde la búsqueda simple hasta la validación compleja y el reemplazo de texto.
Fundamentos del trabajo con NSRegularExpression en Swift
La clase NSRegularExpression proporciona todos los métodos necesarios para trabajar con expresiones regulares. El algoritmo básico de trabajo incluye tres pasos:
- Creación del objeto del patrón de expresión regular
- Aplicación del patrón a la cadena
- Procesamiento de los resultados (coincidencias, reemplazos)
Creación de una expresión regular
Así es como se crea y aplica una expresión regular muy simple para buscar la palabra "Swift":
import Foundation
let text = "Aprendiendo Swift y desarrollo iOS"let pattern = "Swift"
do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { if let range = Range(match.range, in: text) { print("Encontrado: \\(text[range])") } }} catch { print("Error en la expresión regular: \\(error.localizedDescription)")}Tenga en cuenta la conversión de Range — esta es la forma estándar de trabajar con posiciones en cadenas de Swift. Resultado de la ejecución: "Encontrado: Swift".
Ejemplo práctico 1: Búsqueda de direcciones de correo electrónico
Una de las tareas más comunes es extraer direcciones de correo electrónico de un texto. Veamos un ejemplo que encontrará todos los correos electrónicos en una cadena:
import Foundation
func findEmails(in text: String) -> [String] { let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}" var emails: [String] = [] do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { if let range = Range(match.range, in: text) { emails.append(String(text[range])) } } } catch { print("Error: \\(error)") } return emails}
// Ejemplo de usolet sampleText = "Contactos: support@example.com y admin@site.org"let foundEmails = findEmails(in: sampleText)print(foundEmails) // ["support@example.com", "admin@site.org"]Este patrón tiene en cuenta los caracteres estándar permitidos en un correo electrónico y verifica la presencia de un punto en la parte del dominio. Para producción, se puede agregar soporte para dominios cirílicos.
Ejemplo práctico 2: Validación de número de teléfono
La validación de datos de entrada es una parte importante de cualquier aplicación. Así es como se puede verificar un número de teléfono ruso en el formato +7 (XXX) XXX-XX-XX:
import Foundation
func isValidPhoneNumber(_ phone: String) -> Bool { // Patrón para número ruso: +7 (XXX) XXX-XX-XX let pattern = "^\\\\+7\\\\s?\\\\(?[0-9]{3}\\\\)?\\\\s?[0-9]{3}-?[0-9]{2}-?[0-9]{2}$" do { let regex = try NSRegularExpression(pattern: pattern) let range = NSRange(location: 0, length: phone.utf16.count) return regex.firstMatch(in: phone, range: range) != nil } catch { return false }}
// Pruebaslet validNumbers = ["+7 (495) 123-45-67", "+74951234567", "+7 495 1234567"]let invalidNumbers = ["8 (495) 123-45-67", "+7 (495) 123-45-678", "abc"]
for number in validNumbers { print("\\(number): \\(isValidPhoneNumber(number))") // true}
for number in invalidNumbers { print("\\(number): \\(isValidPhoneNumber(number))") // false}El patrón utiliza ancla