Cómo convertir texto a mayúsculas o minúsculas según las reglas de configuración regional
Usa JavaScript para cambiar correctamente el formato de mayúsculas y minúsculas del texto para diferentes idiomas y sistemas de escritura
Introducción
Cuando conviertes texto entre mayúsculas y minúsculas, podrías asumir que esta operación funciona de la misma manera para todos los idiomas. No es así. Diferentes sistemas de escritura siguen diferentes reglas de conversión de mayúsculas y minúsculas, y estas reglas pueden producir resultados inesperados si no las tienes en cuenta.
JavaScript proporciona los métodos estándar toUpperCase() y toLowerCase(), que funcionan correctamente para el inglés pero pueden producir resultados incorrectos para otros idiomas. Los métodos adaptados a la configuración regional toLocaleUpperCase() y toLocaleLowerCase() aplican reglas de conversión de mayúsculas y minúsculas específicas del idioma, asegurando que el texto se transforme correctamente independientemente del idioma.
Esta lección explica por qué la conversión de mayúsculas y minúsculas varía entre idiomas, demuestra problemas específicos que surgen con los métodos estándar y muestra cómo usar métodos adaptados a la configuración regional para manejar correctamente la conversión de mayúsculas y minúsculas en aplicaciones internacionales.
Por qué la conversión de mayúsculas y minúsculas varía según la configuración regional
Las versiones en mayúsculas y minúsculas de las letras no son conceptos universales que funcionen de manera idéntica en todos los sistemas de escritura. Diferentes idiomas desarrollaron diferentes reglas para la conversión de mayúsculas y minúsculas basadas en sus convenciones históricas de escritura y prácticas tipográficas.
En inglés, la conversión de mayúsculas y minúsculas es sencilla. La letra i se convierte en I cuando se pasa a mayúsculas, y I se convierte en i cuando se pasa a minúsculas. Esta relación se mantiene para todo el alfabeto inglés.
Otros idiomas tienen reglas más complejas. El turco tiene cuatro caracteres distintos de la letra i en lugar de dos. El alemán tiene la letra ß (ese aguda), que tiene reglas específicas para la conversión a mayúsculas. El griego tiene diferentes formas de la letra sigma dependiendo de si aparece al final de una palabra.
Cuando utilizas métodos estándar de JavaScript como toUpperCase() y toLowerCase(), la conversión sigue las reglas del inglés. Esto produce resultados incorrectos para texto en otros idiomas. Los métodos adaptados a la configuración regional aplican las reglas apropiadas para cada idioma, asegurando una conversión correcta.
El problema de la i turca
El turco proporciona el ejemplo más claro de por qué la configuración regional importa para la conversión de mayúsculas y minúsculas. A diferencia del inglés, el turco tiene cuatro letras distintas relacionadas con la i:
- I minúscula con punto:
i(U+0069) - İ mayúscula con punto:
İ(U+0130) - ı minúscula sin punto:
ı(U+0131) - I mayúscula sin punto:
I(U+0049)
En turco, la i minúscula con punto se convierte en la İ mayúscula con punto. La ı minúscula sin punto se convierte en la I mayúscula sin punto. Estos son dos pares de letras separados con pronunciaciones y significados distintos.
Los métodos estándar de JavaScript siguen las reglas del inglés y convierten la i con punto en I sin punto. Esto cambia el significado de las palabras turcas y produce texto incorrecto.
const turkish = "istanbul";
console.log(turkish.toUpperCase());
// Output: "ISTANBUL" (incorrect - uses dotless I)
console.log(turkish.toLocaleUpperCase("tr"));
// Output: "İSTANBUL" (correct - uses dotted İ)
El nombre de la ciudad Estambul contiene el carácter i con punto. Cuando se convierte a mayúsculas usando las reglas turcas, se convierte en İSTANBUL con una İ con punto. Usar el método estándar toUpperCase() produce ISTANBUL con una I sin punto, lo cual es incorrecto en turco.
El mismo problema ocurre a la inversa al convertir texto turco en mayúsculas a minúsculas.
const uppercase = "İSTANBUL";
console.log(uppercase.toLowerCase());
// Output: "i̇stanbul" (incorrect - creates i with combining dot above)
console.log(uppercase.toLocaleLowerCase("tr"));
// Output: "istanbul" (correct - produces dotted i)
La İ con punto debería convertirse en la i con punto cuando se pasa a minúsculas en turco. El método estándar toLowerCase() no maneja esto correctamente y puede producir una i minúscula con un carácter de punto combinado, que parece similar pero es técnicamente incorrecto.
Otras reglas de mayúsculas y minúsculas específicas de la configuración regional
El turco no es el único idioma con reglas especiales de conversión de mayúsculas y minúsculas. Varios otros idiomas requieren un manejo específico de la configuración regional.
El alemán tiene la letra ß (ese aguda), que tradicionalmente no tenía forma mayúscula. En 2017, Unicode añadió el carácter mayúsculo ẞ, pero muchos sistemas aún convierten ß a SS al pasar a mayúsculas.
const german = "Straße";
console.log(german.toUpperCase());
// Output: "STRASSE" (converts ß to SS)
console.log(german.toLocaleUpperCase("de"));
// Output: "STRASSE" (also converts ß to SS)
Ambos métodos producen el mismo resultado para texto alemán en la mayoría de entornos JavaScript. El parámetro de idioma no cambia la salida, pero usar el método adaptado al idioma asegura que tu código permanezca correcto si el manejo de Unicode cambia en futuras implementaciones.
El griego tiene tres formas diferentes de la letra sigma. La forma minúscula usa σ en medio de las palabras y ς al final de las palabras. Ambas formas se convierten a la misma mayúscula Σ.
El lituano tiene reglas especiales para letras con punto. La letra i conserva su punto cuando se combina con ciertas marcas diacríticas, incluso al pasar a mayúsculas. Esto afecta cómo los métodos adaptados al idioma manejan combinaciones específicas de caracteres.
Uso de toLocaleUpperCase para la conversión a mayúsculas adaptada al idioma
El método toLocaleUpperCase() convierte una cadena a mayúsculas utilizando reglas de conversión específicas del idioma. Se llama sobre una cadena y opcionalmente se pasa un identificador de idioma como argumento.
const text = "istanbul";
const result = text.toLocaleUpperCase("tr");
console.log(result);
// Output: "İSTANBUL"
Esto convierte la cadena a mayúsculas utilizando las reglas turcas. La i con punto se convierte en İ con punto, que es correcto para el turco.
Puedes convertir el mismo texto utilizando diferentes reglas de idioma.
const text = "istanbul";
console.log(text.toLocaleUpperCase("tr"));
// Output: "İSTANBUL" (Turkish rules - dotted İ)
console.log(text.toLocaleUpperCase("en"));
// Output: "ISTANBUL" (English rules - dotless I)
El parámetro de idioma determina qué reglas de conversión se aplican. Las reglas turcas preservan el punto en la i, mientras que las reglas inglesas no lo hacen.
Si llamas a toLocaleUpperCase() sin argumentos, utiliza el idioma del sistema determinado por el entorno de ejecución de JavaScript.
const text = "istanbul";
const result = text.toLocaleUpperCase();
console.log(result);
// Output depends on system locale
La salida depende del idioma predeterminado del entorno JavaScript, que normalmente coincide con la configuración del sistema operativo del usuario.
Uso de toLocaleLowerCase para la conversión a minúsculas adaptada al idioma
El método toLocaleLowerCase() convierte una cadena a minúsculas utilizando reglas de conversión específicas del idioma. Funciona de la misma manera que toLocaleUpperCase() pero convierte a minúsculas en lugar de mayúsculas.
const text = "İSTANBUL";
const result = text.toLocaleLowerCase("tr");
console.log(result);
// Output: "istanbul"
Esto convierte el texto turco en mayúsculas a minúsculas utilizando las reglas del turco. La İ con punto se convierte en la i con punto, produciendo la forma correcta en minúsculas.
Sin el parámetro de idioma, el estándar toLowerCase() o toLocaleLowerCase() con la configuración de idioma predeterminada puede no manejar correctamente los caracteres turcos.
const text = "İSTANBUL";
console.log(text.toLowerCase());
// Output: "i̇stanbul" (incorrect - i with combining dot above)
console.log(text.toLocaleLowerCase("tr"));
// Output: "istanbul" (correct - dotted i)
La İ con punto del turco requiere las reglas de conversión turcas para convertirse correctamente. Usar el método adaptado al idioma con el idioma tr garantiza la conversión correcta.
También puedes manejar la I sin punto en turco, que debe permanecer sin punto cuando se convierte a minúsculas.
const text = "IRAK";
console.log(text.toLocaleLowerCase("tr"));
// Output: "ırak" (Turkish rules - dotless ı)
console.log(text.toLocaleLowerCase("en"));
// Output: "irak" (English rules - dotted i)
La palabra IRAK (Irak en turco) usa la I sin punto. Las reglas turcas la convierten a la ı minúscula sin punto, mientras que las reglas inglesas la convierten a la i con punto.
Especificación de identificadores de idioma
Tanto toLocaleUpperCase() como toLocaleLowerCase() aceptan identificadores de idioma en formato BCP 47. Estas son las mismas etiquetas de idioma utilizadas en toda la API Intl y otras funciones de internacionalización.
const text = "Straße";
console.log(text.toLocaleUpperCase("de-DE"));
// Output: "STRASSE"
console.log(text.toLocaleUpperCase("de-AT"));
// Output: "STRASSE"
console.log(text.toLocaleUpperCase("de-CH"));
// Output: "STRASSE"
Estos ejemplos utilizan diferentes idiomas alemanes para Alemania, Austria y Suiza. Las reglas de conversión de mayúsculas y minúsculas son generalmente consistentes entre las variantes regionales del mismo idioma, por lo que las tres producen el mismo resultado.
También puedes pasar un array de identificadores de idioma. El método utiliza el primer idioma del array.
const text = "istanbul";
const result = text.toLocaleUpperCase(["tr", "en"]);
console.log(result);
// Output: "İSTANBUL"
El método aplica las reglas turcas porque tr es el primer idioma en el array. Si el entorno de ejecución no admite el primer idioma, recurre a los idiomas subsiguientes en el array.
Uso de las preferencias de configuración regional del navegador
En aplicaciones web, puedes utilizar las preferencias de configuración regional del navegador del usuario para determinar qué reglas de conversión de mayúsculas y minúsculas aplicar. La propiedad navigator.language devuelve el idioma preferido del usuario.
const userLocale = navigator.language;
const text = "istanbul";
const result = text.toLocaleUpperCase(userLocale);
console.log(result);
// Output varies by user's locale
// For Turkish users: "İSTANBUL"
// For English users: "ISTANBUL"
Esto aplica automáticamente las reglas de mayúsculas y minúsculas correctas según la configuración de idioma del usuario. Los usuarios turcos ven el texto convertido usando las reglas turcas, los usuarios de habla inglesa ven el texto convertido usando las reglas inglesas, y así sucesivamente.
También puedes pasar el array completo de preferencias de configuración regional para habilitar el comportamiento de respaldo.
const text = "istanbul";
const result = text.toLocaleUpperCase(navigator.languages);
console.log(result);
El método utiliza la primera configuración regional de las preferencias del usuario, proporcionando un mejor manejo de respaldo cuando configuraciones regionales específicas no están disponibles.
Comparación de métodos estándar y adaptados a la configuración regional
Los métodos estándar toUpperCase() y toLowerCase() funcionan correctamente para el inglés pero pueden fallar para otros idiomas. Los métodos adaptados a la configuración regional toLocaleUpperCase() y toLocaleLowerCase() manejan todos los idiomas correctamente aplicando reglas específicas de cada configuración regional.
const turkish = "Diyarbakır";
// Standard methods (incorrect for Turkish)
console.log(turkish.toUpperCase());
// Output: "DIYARBAKIR" (dotless I - incorrect)
console.log(turkish.toUpperCase().toLowerCase());
// Output: "diyarbakir" (dotted i - lost the dotless ı)
// Locale-aware methods (correct for Turkish)
console.log(turkish.toLocaleUpperCase("tr"));
// Output: "DİYARBAKIR" (dotted İ and dotless I - correct)
console.log(turkish.toLocaleUpperCase("tr").toLocaleLowerCase("tr"));
// Output: "diyarbakır" (preserves both i types - correct)
El nombre de la ciudad turca Diyarbakır contiene ambos tipos de i. Los métodos estándar no pueden preservar esta distinción al convertir de un caso a otro. Los métodos adaptados a la configuración regional mantienen los caracteres correctos en ambas direcciones.
Para texto que solo contiene caracteres con reglas de mayúsculas y minúsculas simples, ambos enfoques producen resultados idénticos.
const english = "Hello World";
console.log(english.toUpperCase());
// Output: "HELLO WORLD"
console.log(english.toLocaleUpperCase("en"));
// Output: "HELLO WORLD"
El texto en inglés se convierte de la misma manera con cualquiera de los métodos. La versión adaptada a la configuración regional no es necesaria para texto exclusivamente en inglés, pero usarla asegura que tu código funcione correctamente si el texto contiene otros idiomas.
Cuándo usar conversión de mayúsculas y minúsculas adaptada a la configuración regional
Utiliza métodos adaptados a la configuración regional cuando trabajes con contenido generado por usuarios o texto que pueda incluir múltiples idiomas. Esto asegura una conversión correcta de mayúsculas y minúsculas independientemente del idioma que contenga el texto.
function normalizeUsername(username) {
return username.toLocaleLowerCase();
}
Los nombres de usuario, direcciones de correo electrónico, términos de búsqueda y otras entradas del usuario deben usar conversión consciente de la configuración regional. Esto maneja correctamente los caracteres internacionales y previene problemas con el turco y otros casos especiales.
Usa métodos estándar solo cuando sepas que el texto contiene únicamente caracteres en inglés y necesites el máximo rendimiento. Los métodos estándar se ejecutan ligeramente más rápido porque no necesitan verificar las reglas de configuración regional.
const htmlTag = "<DIV>";
const normalized = htmlTag.toLowerCase();
// Output: "<div>"
Los nombres de etiquetas HTML, propiedades CSS, esquemas de protocolo y otros identificadores técnicos usan caracteres ASCII y no requieren conocimiento de la configuración regional. Los métodos estándar funcionan correctamente para este contenido.
Cómo puede cambiar la longitud de caracteres después de la conversión
La conversión de mayúsculas y minúsculas no siempre es un mapeo de caracteres uno a uno. Algunos caracteres se expanden en múltiples caracteres cuando se convierten a mayúsculas, lo que afecta la longitud de la cadena.
const german = "groß";
console.log(german.length);
// Output: 4
const uppercase = german.toLocaleUpperCase("de");
console.log(uppercase);
// Output: "GROSS"
console.log(uppercase.length);
// Output: 5
La palabra alemana groß tiene cuatro caracteres. Cuando se convierte a mayúsculas, la ß se convierte en SS, produciendo GROSS con cinco caracteres. La longitud de la cadena aumenta en un carácter durante la conversión.
Esto afecta las operaciones que dependen de la longitud de la cadena o las posiciones de los caracteres. No asumas que la versión en mayúsculas o minúsculas de una cadena tiene la misma longitud que la original.
const text = "Maße";
const positions = [0, 1, 2, 3];
const uppercase = text.toLocaleUpperCase("de");
// "MASSE" (5 characters)
// Original position mapping no longer valid
La ß en la posición 2 se convierte en SS en la versión en mayúsculas, desplazando todos los caracteres subsiguientes. Las posiciones de caracteres de la cadena original no se corresponden con las posiciones en la cadena convertida.
Reutilización de parámetros de configuración regional
Si necesitas convertir múltiples cadenas usando la misma configuración regional, puedes almacenar el identificador de configuración regional en una variable y reutilizarlo. Esto hace que tu código sea más mantenible y garantiza un manejo consistente de la configuración regional.
const userLocale = navigator.language;
const city = "istanbul";
const country = "türkiye";
console.log(city.toLocaleUpperCase(userLocale));
console.log(country.toLocaleUpperCase(userLocale));
Este enfoque mantiene la selección de configuración regional en un solo lugar. Si necesitas cambiar qué configuración regional usas, solo necesitas actualizar la definición de la variable.
Para aplicaciones que procesan grandes cantidades de texto, esto no proporciona un beneficio de rendimiento. Cada llamada a toLocaleUpperCase() o toLocaleLowerCase() realiza la conversión de forma independiente. A diferencia de los formateadores de la API Intl, no hay un objeto formateador para reutilizar.