Cómo convertir texto a mayúsculas o minúsculas según las reglas de localización
Utiliza JavaScript para cambiar correctamente el caso del texto para diferentes idiomas y sistemas de escritura
Introducción
Cuando conviertes texto entre mayúsculas y minúsculas, podrías suponer 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 al idioma 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 al idioma 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 funcionan 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 pone en mayúsculas, y I se convierte en i cuando se pone en 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 para la letra i en lugar de dos. El alemán tiene la letra ß (eszett), 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 textos en otros idiomas. Los métodos adaptados al idioma 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());
// Resultado: "ISTANBUL" (incorrecto - usa I sin punto)
console.log(turkish.toLocaleUpperCase("tr"));
// Resultado: "İSTANBUL" (correcto - usa İ con punto)
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 estándar toUpperCase() produce ISTANBUL con una I sin punto, lo cual es incorrecto en turco.
El mismo problema ocurre a la inversa cuando se convierte texto turco en mayúsculas a minúsculas.
const uppercase = "İSTANBUL";
console.log(uppercase.toLowerCase());
// Resultado: "i̇stanbul" (incorrecto - crea i con punto combinado arriba)
console.log(uppercase.toLocaleLowerCase("tr"));
// Resultado: "istanbul" (correcto - produce i con punto)
La İ con punto debería convertirse en la i con punto cuando se pasa a minúsculas en turco. El 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 según la configuración regional.
El alemán tiene la letra ß (eszett), que tradicionalmente no tenía forma mayúscula. En 2017, Unicode añadió el carácter ẞ mayúscula, pero muchos sistemas todavía convierten ß a SS cuando se pasa a mayúsculas.
const german = "Straße";
console.log(german.toUpperCase());
// Resultado: "STRASSE" (convierte ß a SS)
console.log(german.toLocaleUpperCase("de"));
// Resultado: "STRASSE" (también convierte ß a SS)
Ambos métodos producen el mismo resultado para texto alemán en la mayoría de los entornos JavaScript. El parámetro de configuración regional no cambia el resultado, pero usar el método compatible con la configuración regional asegura que tu código permanezca correcto si el manejo de Unicode cambia en implementaciones futuras.
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 las letras con punto. La letra i mantiene su punto cuando se combina con ciertas marcas diacríticas, incluso cuando se convierte a mayúsculas. Esto afecta cómo los métodos compatibles con la configuración regional 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 invoca sobre una cadena y opcionalmente se puede pasar un identificador de idioma como argumento.
const text = "istanbul";
const result = text.toLocaleUpperCase("tr");
console.log(result);
// Resultado: "İSTANBUL"
Esto convierte la cadena a mayúsculas utilizando las reglas del turco. La i con punto se convierte en İ con punto, lo cual es correcto en turco.
Puedes convertir el mismo texto utilizando reglas de diferentes idiomas.
const text = "istanbul";
console.log(text.toLocaleUpperCase("tr"));
// Resultado: "İSTANBUL" (reglas turcas - İ con punto)
console.log(text.toLocaleUpperCase("en"));
// Resultado: "ISTANBUL" (reglas inglesas - I sin punto)
El parámetro de idioma determina qué reglas de conversión se aplican. Las reglas turcas conservan el punto sobre 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);
// El resultado depende del idioma del sistema
El resultado 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);
// Resultado: "istanbul"
Esto convierte el texto turco en mayúsculas a minúsculas utilizando las reglas turcas. La İ con punto se convierte en 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());
// Resultado: "i̇stanbul" (incorrecto - i con punto combinado arriba)
console.log(text.toLocaleLowerCase("tr"));
// Resultado: "istanbul" (correcto - i con punto)
La İ con punto turca requiere reglas de conversión turcas para convertirse correctamente. Usar el método adaptado al idioma con el idioma tr asegura una 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"));
// Resultado: "ırak" (reglas turcas - ı sin punto)
console.log(text.toLocaleLowerCase("en"));
// Resultado: "irak" (reglas inglesas - i con punto)
La palabra IRAK (Iraq en turco) utiliza la I sin punto. Las reglas de conversión turcas la convierten a minúscula ı sin punto, mientras que las reglas inglesas la convierten a i con punto.
Especificando identificadores de localización
Tanto toLocaleUpperCase() como toLocaleLowerCase() aceptan identificadores de localización en formato BCP 47. Estas son las mismas etiquetas de idioma utilizadas en toda la API de Intl y otras características de internacionalización.
const text = "Straße";
console.log(text.toLocaleUpperCase("de-DE"));
// Resultado: "STRASSE"
console.log(text.toLocaleUpperCase("de-AT"));
// Resultado: "STRASSE"
console.log(text.toLocaleUpperCase("de-CH"));
// Resultado: "STRASSE"
Estos ejemplos utilizan diferentes localizaciones alemanas para Alemania, Austria y Suiza. Las reglas de conversión de mayúsculas y minúsculas son generalmente consistentes en todas las variantes regionales del mismo idioma, por lo que las tres producen el mismo resultado.
También puedes pasar un array de identificadores de localización. El método utiliza la primera localización en el array.
const text = "istanbul";
const result = text.toLocaleUpperCase(["tr", "en"]);
console.log(result);
// Resultado: "İSTANBUL"
El método aplica las reglas turcas porque tr es la primera localización en el array. Si el entorno de ejecución no admite la primera localización, recurre a las localizaciones subsiguientes en el array.
Usando las preferencias de localización del navegador
En aplicaciones web, puedes utilizar las preferencias de localización 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);
// El resultado varía según la localización del usuario
// Para usuarios turcos: "İSTANBUL"
// Para usuarios ingleses: "ISTANBUL"
Esto aplica automáticamente las reglas correctas de mayúsculas y minúsculas según la configuración de idioma del usuario. Los usuarios turcos ven el texto convertido usando reglas turcas, los usuarios ingleses ven el texto convertido usando reglas inglesas, y así sucesivamente.
También puedes pasar todo el array de preferencias de localización para habilitar el comportamiento de respaldo.
const text = "istanbul";
const result = text.toLocaleUpperCase(navigator.languages);
console.log(result);
El método utiliza la primera localización de las preferencias del usuario, proporcionando un mejor manejo de respaldo cuando ciertas localizaciones específicas no están disponibles.
Comparación de métodos estándar y métodos 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";
// Métodos estándar (incorrectos para el turco)
console.log(turkish.toUpperCase());
// Resultado: "DIYARBAKIR" (I sin punto - incorrecto)
console.log(turkish.toUpperCase().toLowerCase());
// Resultado: "diyarbakir" (i con punto - se perdió la ı sin punto)
// Métodos adaptados a la configuración regional (correctos para el turco)
console.log(turkish.toLocaleUpperCase("tr"));
// Resultado: "DİYARBAKIR" (İ con punto y I sin punto - correcto)
console.log(turkish.toLocaleUpperCase("tr").toLocaleLowerCase("tr"));
// Resultado: "diyarbakır" (preserva ambos tipos de i - correcto)
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 entre mayúsculas y minúsculas. 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 conversión simples, ambos enfoques producen resultados idénticos.
const english = "Hello World";
console.log(english.toUpperCase());
// Resultado: "HELLO WORLD"
console.log(english.toLocaleUpperCase("en"));
// Resultado: "HELLO WORLD"
El texto en inglés se convierte de la misma manera con cualquier método. La versión adaptada a la configuración regional no es necesaria para texto exclusivamente en inglés, pero usarla garantiza que tu código funcione correctamente si el texto contiene otros idiomas.
Cuándo usar la conversión de mayúsculas y minúsculas adaptada a la configuración regional
Utiliza los métodos adaptados a la configuración regional cuando trabajes con contenido generado por usuarios o texto que pueda incluir múltiples idiomas. Esto garantiza 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 de usuario deberían usar conversión adaptada a la configuración regional. Esto maneja correctamente los caracteres internacionales y previene problemas con el turco y otros casos especiales.
Utiliza los 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();
// Resultado: "<div>"
Los nombres de etiquetas HTML, propiedades CSS, esquemas de protocolo y otros identificadores técnicos utilizan caracteres ASCII y no requieren adaptación a 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 a 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 caracteres)
// El mapeo de posición original ya no es válido
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 corresponden a las posiciones en la cadena convertida.
Reutilización de parámetros de configuración regional
Si necesitas convertir múltiples cadenas utilizando 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 asegura 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 utilizas, 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.