He buscado en Stack Overflow ( reemplazando caracteres ... eh , cómo JavaScript no sigue el estándar Unicode sobre RegExp , etc.) y realmente no he encontrado una respuesta concreta a la pregunta:
How can JavaScript match for accented characters (those with diacritical marks)?
Estoy forzando un campo en una interfaz de usuario para que coincida con el formato: last_name, first_name
(último [espacio de coma] primero) , y quiero proporcionar soporte para diacríticos, pero evidentemente en JavaScript es un poco más difícil que otros idiomas / plataformas.
Esta era mi versión original, hasta que quería agregar soporte diacrítico:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
Actualmente estoy debatiendo uno de los tres métodos para agregar soporte, todos los cuales he probado y trabajo (al menos hasta cierto punto, realmente no sé cuál es el "alcance" del segundo enfoque). Aquí están:
Enumerar explícitamente todos los caracteres acentuados que me gustaría aceptar como válidos (cojos y demasiado complicados):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
- Esto coincide correctamente un apellido / nombre con cualquiera de los caracteres acentuados admitidos en
accentedCharacters
.
Mi otro enfoque era usar la .
clase de caracteres, para tener una expresión más simple:
var regex = /^.+,\s.+$/;
- Esto coincidiría para casi cualquier cosa, por lo menos en la forma de:
something, something
. Eso está bien, supongo ...
El último enfoque, que acabo de encontrar, podría ser más simple ...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Coincide con una variedad de caracteres Unicode, probados y funcionando, aunque no intenté nada loco, solo las cosas normales que veo en nuestro departamento de idiomas para los nombres de los miembros de la facultad.
Aquí están mis preocupaciones:
- La primera solución es demasiado limitante y descuidada y complicada. Tendría que cambiarlo si olvido un personaje o dos, y eso no es muy práctico.
- La segunda solución es mejor, concisa, pero probablemente coincida mucho más de lo que debería. No pude encontrar ninguna documentación real sobre exactamente qué
.
coincide, solo la generalización de "cualquier carácter excepto el carácter de nueva línea" (de una tabla en el MDN ). La tercera solución parece ser la más precisa, pero ¿hay alguna trampa? No estoy muy familiarizado con Unicode, al menos en la práctica, pero mirar una tabla de códigos / continuación de esa tabla ,
\u00C0-\u017F
parece ser bastante sólido, al menos para mi entrada esperada.- La facultad no enviará formularios con sus nombres en su idioma nativo (por ejemplo, árabe, chino, japonés, etc.), por lo que no tengo que preocuparme por los caracteres fuera del latín.
Entonces, la (s) verdadera (s) pregunta (s) : ¿Cuál de estos tres enfoques es el más adecuado para la tarea? ¿O hay mejores soluciones?
fuente
regex = /^[^,]+,\s[^,]+$/;
para evitar eso..
átomo coincide con cualquier cosa excepto las líneas nuevas " en realidad es bastante exacto :-)Respuestas:
La forma más fácil de aceptar todos los acentos es esta:
Consulte https://unicode-table.com/en/ para ver los caracteres enumerados en orden numérico.
fuente
-
define un rango, y esta técnica explota el orden de los personajes en el juego de caracteres para definir un rango continuo, lo que lo convierte en una solución súper concisa para el problemaZ
ya
)?El rango latino acentuado
\u00C0-\u017F
no era suficiente para mi base de datos de nombres, así que extendí la expresión regular aAgregué estos bloques de código (
\u00C0-\u024F
incluye tres bloques adyacentes a la vez):\u00C0-\u00FF
Suplemento Latin-1\u0100-\u017F
Latin Extended-A\u0180-\u024F
Latin Extended-B\u1E00-\u1EFF
Latín Extendido AdicionalTenga en cuenta que en
\u00C0-\u00FF
realidad es solo una parte del suplemento Latin-1 . Ese rango omite las señales de control no imprimibles y todos los símbolos, excepto la multiplicación x\u00D7
y la división ÷\u00F7
.Si necesita más puntos de código, puede encontrar más rangos en la Lista de caracteres Unicode de Wikipedia . Por ejemplo, también podría agregar Latin Extended-C , D y E , pero los omití porque solo los historiadores parecen interesados en ellos ahora, y los conjuntos D y E ni siquiera se muestran correctamente en mi navegador.
La expresión regular original se detuvo en
\u017F
el nombre "Șenol". De acuerdo con el analizador Unicode de FontSpace , ese primer personaje es\u0218
, LETRA DE CAPITAL LATINO S CON COMA ABAJO. (Sí, generalmente se deletrea con una cedilla-S\u015E
, "Şenol". Pero no voy a volar a Turquía para ir a decirle: "¡Estás deletreando mal tu nombre!")fuente
[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
Depende de la tarea :-) Para que coincida exactamente con todos los caracteres latinos y sus versiones acentuadas, los rangos Unicode probablemente brinden la mejor solución. Podrían extenderse a todos los caracteres que no sean espacios en blanco, lo que podría hacerse utilizando la
\S
clase de caracteres.El problema más básico que estoy viendo aquí no son los signos diacríticos, sino los espacios en blanco. Hay algunos nombres que consisten en varias palabras, por ejemplo, para títulos. Por lo tanto, debe elegir el más genérico, que permite todo menos la coma que distingue el nombre del apellido:
Pero su segunda solución con la
.
clase de caracteres es igual de buena, entonces es posible que solo deba preocuparse por múltiples comas.fuente
any_character_not_a_comma, any_character_not_a_comma
? Eso es lo que pensé cuando lo leí por primera vez, me confundí cuando vi tres comas allí.s
para el espacio en blanco ...[^\s]
a\S
La biblioteca XRegExp tiene un complemento llamado Unicode que ayuda a resolver tareas como esta.
Se menciona en los comentarios a la pregunta, pero es fácil pasarlo por alto. Lo noté solo después de enviar esta respuesta.
fuente
anything, anything
. Esto será útil para futuros lectores :)¿Qué tal esto?
fuente
Šš
.¿Qué hay de esto?
Emparejará cada palabra con caracteres acentuados o no.
fuente
de este wiki: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
para letras latinas, yo uso
evita guiones y caracteres especiales
fuente
Explicación:
\pL
- coincide con cualquier tipo de letra de cualquier idioma\pM
- asigna un carácter destinado a combinarse con otro carácter (por ejemplo, acentos, diéresis, cajas de cerramiento, etc.)\p{Zs}
- coincide con un carácter de espacio en blanco que es invisible, pero ocupa espaciou
- Las cadenas de patrones y temas se tratan como UTF-8A diferencia de otras expresiones regulares propuestas (como
[A-Za-zÀ-ÖØ-öø-ÿ]
), esto funcionará con todos los caracteres específicos del idioma, por ejemplo,Šš
coincide con esta regla, pero no coincide con otros en esta página.Desafortunadamente, JavaScript de forma nativa no admite estas clases. Sin embargo, puede usar
xregexp
, por ejemplofuente
Puede eliminar los signos diacríticos de los alfabetos utilizando:
Eliminará todos los signos diacríticos y luego realizará su expresión regular en él
Referencia:
https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/
fuente