Quiero obtener el acento/diacrítico de una letra en javascript.
Por ejemplo:
ñ -> ~á -> ´è -> ` Intenté usar .normalize("NFD") pero no devuelve el acento/diacrítico correcto
string = "á" string.normalize("NFD").split("") // ['a', '́'] string.normalize("NFD").split("").includes("´") // false '́' === "´" // false Quiero NFD o cualquier otra función para dar el acento/diacrítico en lugar de la combinación de acento/diacrítico
La respuesta corta es porque COMBINING TILDE != TILDE
Aquí hay un desglose de cada uno de los caracteres Unicode potencialmente involucrados en ñ por ejemplo:
| Símbolo | Código | Punto de código | Nombre |
|---|---|---|---|
| norte | \u00F1 | 241 | LETRA N MINÚSCULA LATINA CON TILDE |
| norte | \u006E | 110 | LETRA N MINÚSCULA LATINA |
| ̃ | \u0303 | 771 | COMBINANDO TILDE |
| ~ | \u007E | 126 | tilde |
Para poder separar los signos diacríticos de sus caracteres adjuntos, puede usar string.normalize con "NFD" que proporciona la " descomposición canónica", dividiendo un solo glifo en diferentes combinaciones de caracteres que dan como resultado el mismo símbolo.
Hay 112 signos diacríticos combinados diferentes. No puedo encontrar una forma nativa de convertir entre el personaje combinado y su contraparte en solitario. Puede buscar una biblioteca o escribir el mapeo usted mismo para las marcas que desea manejar de esta manera:
const combiningMarks = { 771: 126, // tilde 769: 180, // acute accent 768: 96, // grave accent }Luego descomponga en caracteres separados y busque la marca asociada para cada carácter combinado como este:
const combiningMarks = { 771: 126, // tilde 769: 180, // acute accent 768: 96, // grave accent } const startingString = "ñáè" // "\u00F1\u00E1\u00E8" const decomposedString = startingString.normalize("NFD") // "\u006E\u0303\u0061\u0301\u0065\u0300" const codepoints = [...decomposedString].map(c => c.codePointAt(0)) // [110, 771, 97, 769, 101, 768] const charsWithFullMarks = codepoints.map(c => combiningMarks[c] || c) // [110, 126, 97, 180, 101, 96] const finalString = String.fromCodePoint(...charsWithFullMarks) // "n~a´e`" console.log(finalString);Su método para obtener el acento/diacrítico de una letra es correcto usando string.normalize("NFD").split("") .
La normalize("NFD") devuelve el resultado correcto , que en este caso es el Código decimal Unicode de acento agudo combinado ́.
Sin embargo, lo que está haciendo es comparar la salida de la letra á de la normalize("NFD") , que es el acento agudo combinado (código de caracteres 769 ) con el acento agudo normal (código de caracteres 180 ). Por supuesto, estas son 2 letras diferentes.
Lo mismo se aplica a la letra è que tiene el acento grave combinado (código char 768 ); y lo está comparando con el acento grave normal (código char 96 ) que usamos y escribimos desde el teclado; son 2 letras diferentes
Las letras independientes (normales) (incluidas las letras de acento agudo y acento grave) siempre serán letras separadas, incluso si vienen antes o después de cualquier otra letra en una cadena. Sin embargo, las formas de combinación de las letras (que tienen diferentes códigos de caracteres para distinguirlas) estarán por encima o por debajo de la letra siguiente o anterior a la que están adyacentes. Esto es similar en las letras con acento árabe y otros idiomas como el hebreo.
Aquí hay comparaciones de algunas de las letras tilde:
Vea a continuación los ejemplos:
console.log("á".normalize("NFD").split("")[1].charCodeAt()); // 769 code for Combining Acute Accent console.log("´".charCodeAt()); // 180 code for Normal Acute Accent console.log("è".normalize("NFD").split("")[1].charCodeAt()); // 768 Combining Grave Accent console.log("`".charCodeAt()); // 96 Normal Grave Accent console.log("á".normalize("NFD").split("")[1].charCodeAt()); // 769 code for Combining Acute Accent console.log("´".charCodeAt()); // 180 code for Normal Acute Accent console.log("è".normalize("NFD").split("")[1].charCodeAt()); // 768 Combining Grave Accent console.log("`".charCodeAt()); // 96 Normal Grave Accent