2011-03-25 14 views
46

He aquí un fragmento de diversión me encontré hoy:a juego con los caracteres acentuados Javascript expresiones regulares

/\ba/.test("a") --> true 
/\bà/.test("à") --> false 

Sin embargo,

/à/.test("à") --> true 

En primer lugar, wtf?

En segundo lugar, si quiero hacer coincidir un carácter acentuado al comienzo de una palabra, ¿cómo puedo hacer eso? (Realmente me gustaría evitar el uso de selectores over-the-top como /(?:^|\s|'|\(\) ....)

+8

La respuesta a su WTF es que Javascript no maneja Unicode correctamente en las expresiones regulares. Ver [el estándar] (http://unicode.org/reports/tr18/#Compatibility_Properties) para ver cómo se supone que funciona. O use un lenguaje que cumpla con los estándares en este sentido. Solo por nombrar algunas ... en expresiones regulares de Perl, PHP, PCRE e ICU, '" à "' sin duda coincide con el patrón '/ \ bà /'. Son mucho mejores para el trabajo Unicode. – tchrist

+0

es posible que desee eliminar acentos y luego haga una simple comprobación [a-z]. ver http://stackoverflow.com/questions/990904/javascript-remove-accents-in-strings –

Respuesta

38

La razón por la que /\bà/.test("à") no coincide es porque "à" no es un carácter de palabra. La secuencia de escape \b coincide solo entre un límite de carácter de palabra y un carácter de palabra distinta. /\ba/.test("a") coincide porque "a" es un carácter de palabra. Por eso, hay un límite entre el comienzo de la cadena (que no es un carácter de palabra) y la letra "a" que es un carácter de palabra.

Los caracteres de Word en la expresión regular de JavaScript se definen como [a-zA-Z0-9_].

Para hacer coincidir un carácter acentuado al comienzo de una cadena, simplemente utilice el carácter ^ al comienzo de la expresión regular (por ejemplo, /^à/). Ese carácter significa el comienzo de la cadena (a diferencia de \b que coincide con cualquier límite de palabra dentro de la cadena). Es la expresión regular más básica y estándar, por lo que definitivamente no es exagerado.

+0

Ah ok eso explica muchas cosas, pero supongo que dije algo incorrecto en mi pregunta original. Necesito hacer coincidir al comienzo de una palabra, no una cadena. La razón por la que creo que el selector sería "over-the-top" sería porque tendría que coincidir con el comienzo de una cadena, espacios, corchetes, comas, puntos completos ... – nickf

+1

+1 Solo agregaría eso con el El método 're.test()', uno debe conocer el comportamiento de la propiedad 're.lastIndex' que contiene el desplazamiento de la última coincidencia (y es donde se iniciará el siguiente intento de coincidencia).Esto no se aplica en este caso, ya que el método se aplica a un literal de expresión regular, pero esto sí importa si el objeto de expresión regular se almacena en una variable y luego se usa más de una vez. – ridgerunner

+0

Javascript está fuera de cumplimiento con [El estándar Unicode] (http://unicode.org/reports/tr18/#Compatibility_Properties), porque el estándar citado claramente establece que cosas como à están destinadas a ser emparejadas por '\ w 'en expresiones regulares. – tchrist

2

Stack Overflow también tenía un problema con los caracteres no ASCII en la expresión regular, puede encontrarlo here. No están lidiando con los límites de las palabras, pero tal vez te brinde consejos útiles.

Hay otro page, pero quiere hacer coincidir cadenas y no palabras.

No sé, y no encontré ahora, un ancla para su problema, pero cuando veo qué monstruo expresiones regulares en mi primer enlace se utilizan, su grupo, que desea evitar, no es excesivo y en mi opinión tu solución.

56

Esto funcionó para mí:

/^[a-z\u00E0-\u00FC]+$/i 

Con la ayuda de here

+40

Con su expresión regular echas de menos las letras francesas 'ÿ' y 'œ'. Pruebe '/^[A-Za-z \ u00C0- \ u017F] + $ /' para obtenerlos todos. –

+5

¿cuál es el equivalente para caracteres en mayúscula? –

+32

ya que cuando '' es una letra francesa: D (hablante nativo aquí ...) –

Cuestiones relacionadas