¿Cómo verificar si una cadena contiene una subcadena en Swift? Guía completa
\n\n¡Hola, colega desarrollador! Si alguna vez has escrito en Swift y te has preguntado: «¿Cómo encuentro una palabra dentro de otra?», has llegado al lugar indicado. Este tema es una de las preguntas más populares en Stack Overflow (la versión en inglés tiene cientos de miles de visitas). Y no es casualidad: trabajar con cadenas es la base sin la que ninguna aplicación puede funcionar.
\n\nEn este artículo, analizaremos todas las formas legítimas de verificar si una cadena contiene una subcadena. Desde el más simple contains() hasta técnicas avanzadas con búsqueda que no distingue mayúsculas de minúsculas y expresiones regulares. ¡Allá vamos!
1. La forma más simple: el método contains()
\n\nDesde Swift 1.0, tenemos el método integrado contains() en el tipo String. Funciona de forma intuitiva y es muy rápido.
let fullString = "¡Hola, mundo Swift!"\nlet searchString = "Swift"\n\nif fullString.contains(searchString) {\n print("Sí, la cadena contiene '\\(searchString)'")\n} else {\n print("No, no contiene")\n}\n// Salida: Sí, la cadena contiene 'Swift'\n\nImportante: el método contains() distingue entre mayúsculas y minúsculas. Es decir, "swift" no se encontrará en la cadena "Swift". Pero lo solucionaremos un poco más adelante.
2. Búsqueda que no distingue mayúsculas de minúsculas: localizedCaseInsensitiveContains()
\n\nA menudo es necesario encontrar una palabra sin importar las mayúsculas. Para ello, existe un método especial que funciona teniendo en cuenta la configuración regional del usuario.
\n\nlet text = "Bienvenido a Swift"\nlet search = "swift"\n\nif text.localizedCaseInsensitiveContains(search) {\n print("¡Encontrado! Las mayúsculas no son un problema.")\n} else {\n print("No encontrado")\n}\n// Salida: ¡Encontrado! Las mayúsculas no son un problema.\n\nEste método utiliza la configuración regional actual del dispositivo, lo que es especialmente importante para idiomas con reglas de comparación especiales (por ejemplo, el turco, donde «i» e «I» son letras diferentes).
\n\n3. Búsqueda con configuración regional: localizedStandardContains()
\n\nOtro método útil es localizedStandardContains(). Realiza la búsqueda de la misma manera que la búsqueda estándar en iOS (por ejemplo, en Spotlight o Finder).
let fileName = "Foto_vacaciones_2024.jpg"\nlet query = "vacaciones"\n\nif fileName.localizedStandardContains(query) {\n print("¡Archivo encontrado!")\n}\n// Salida: ¡Archivo encontrado!\n\nEste método normaliza automáticamente las cadenas, elimina las marcas diacríticas (por ejemplo, «é» = «e») y funciona sin distinguir mayúsculas de minúsculas. Ideal para cadenas de búsqueda en la interfaz.
\n\n4. La forma clásica: range(of:)
\n\nA veces no solo necesitas saber si existe una subcadena, sino también obtener su posición. Aquí es donde range(of:) viene al rescate. Devuelve un rango opcional (Range<String.Index>?).
let phrase = "Aprendiendo Swift en pythonlib.ru"\nlet word = "Swift"\n\nif let range = phrase.range(of: word) {\n print("Subcadena encontrada en la posición: \\(range.lowerBound)")\n // Incluso puedes extraer una parte de la cadena\n let extracted = phrase[range]\n print("Extraído: \\(extracted)")\n} else {\n print("Subcadena no encontrada")\n}\n\nPara la búsqueda que no distingue mayúsculas de minúsculas con range, usa la opción .caseInsensitive:
if let range = phrase.range(of: "swift", options: .caseInsensitive) {\n print("Encontrado sin distinguir mayúsculas: \\(phrase[range])")\n}\n\n5. Verificación del inicio y final de la cadena
\n\nA veces es necesario verificar no «si contiene en general», sino «si comienza con...» o «si termina en...». Para ello, existen métodos especiales:
\n\nlet url = "https://pythonlib.ru"\n\nif url.hasPrefix("https://") {\n print("Esta es una URL segura")\n}\n\nif url.hasSuffix(".ru") {\n print("Dominio ruso")\n}\n\nAmbos métodos también distinguen entre mayúsculas y minúsculas.