¿Cómo puedo usar expresiones regulares compatibles con Unicode en JavaScript?
Por ejemplo, debería haber algo similar a \w
eso que pueda coincidir con cualquier punto de código en la categoría de Letras o Marcas (no solo las de ASCII), y es de esperar que tenga filtros como [[P *]] para la puntuación, etc.
javascript
regex
unicode
character-properties
Peter Mortensen
fuente
fuente
Respuestas:
Situación para ES 6
La próxima especificación del lenguaje ECMAScript, edición 6, incluye expresiones regulares compatibles con Unicode. El soporte debe estar habilitado con el
u
modificador en la expresión regular. Consulte Expresiones regulares compatibles con Unicode en ES6 .Sin embargo, hasta que ES 6 esté terminado y sea ampliamente adoptado entre los proveedores de navegadores, usted seguirá solo. Actualización: ahora hay un transpiler llamado regexpu que traduce las expresiones regulares Unicode de ES6 en ES5 equivalente. Se puede usar como parte de su proceso de compilación. Pruébalo en línea.
Situación para ES 5 y menos
Aunque JavaScript opera en cadenas Unicode, no implementa clases de caracteres compatibles con Unicode y no tiene el concepto de clases de caracteres POSIX o bloques / subrangos Unicode.
Problemas con Unicode en expresiones regulares de JavaScript
Verifique sus expectativas aquí: JavaScript RegExp Unicode Character Class tester ( Editar: la página original está inactiva, el Archivo de Internet todavía tiene una copia ).
Flagrant Badassery tiene un artículo sobre JavaScript, Regex y Unicode que arroja algo de luz sobre el asunto.
Lea también Regex y Unicode aquí en SO. Probablemente tenga que construir su propia "clase de puntuación".
Consulte el constructor Expresión regular: Coincidencia del rango de bloques Unicode , que le permite crear una expresión regular de JavaScript que coincida con los caracteres que se encuentran en cualquier número de bloques Unicode especificados.
Lo acabo de hacer para los subrangos "Puntuación general" y "Puntuación complementaria", y el resultado es tan simple y directo como lo hubiera esperado:
También existe XRegExp , un proyecto que brinda soporte Unicode a JavaScript al ofrecer un motor de expresiones regulares alternativo con capacidades extendidas.
Y, por supuesto, lectura obligatoria: mathiasbynens.be - JavaScript tiene un problema Unicode :
fuente
u
pabellón, así como algunas otras características ES6 para trabajar con Unicode.u
expresiones regulares."a品cd!e f".replace(/[^\w]/ug, "")
pero la expresión regular resultante (ejecutada en Chrome 59) todavía elimina el品
personaje y solo regresa"acdef"
Personalmente, preferiría no instalar otra biblioteca solo para obtener esta funcionalidad. Mi respuesta no requiere ninguna biblioteca externa, y también puede funcionar con pocas modificaciones para los sabores de expresiones regulares además de JavaScript.
El sitio web de Unicode proporciona una manera de traducir las categorías de Unicode en un conjunto de puntos de código. Dado que es el sitio web de Unicode , la información del mismo debe ser precisa.
Tenga en cuenta que deberá excluir los caracteres de gama alta, ya que JavaScript solo puede manejar caracteres de menos de
FFFF
(hexadecimal). Sugiero que marque las casillas de verificación Agrupar clasificación y Escape, que logran un equilibrio entre evitar caracteres no imprimibles y minimizar el tamaño de la expresión regular.Estas son algunas expansiones comunes de diferentes propiedades Unicode:
\p{L}
(Letras):\p{Nd}
(Número de dígitos decimales):\p{P}
(Puntuación):La página también reconoce una serie de clases de caracteres oscuros, como
\p{Hira}
, que son solo los caracteres (japoneses) de Hiragana:Por último, es posible conectar una clase char con más de una propiedad Unicode para obtener una expresión regular más corta de la que obtendría simplemente combinándolas (siempre que se verifiquen ciertas configuraciones).
fuente
\p
-La sintaxis no parece funcionar en JS,/\p{L}/.test('a')
esfalse
Al no haber encontrado una buena solución, escribí un pequeño script hace mucho tiempo, descargando datos de la especificación Unicode (v.5.0.0) y generando intervalos para cada categoría y subcategoría Unicode en el BMP (recientemente reemplazado por un pequeño Programa Java que utiliza su propio soporte nativo Unicode).
Básicamente se convierte
\p{...}
en un rango de valores, muy similar a la salida de la herramienta. mencionada por Tomalak, pero los intervalos pueden terminar bastante largos (ya que no se trata de bloques, sino de caracteres dispersos en muchos lugares diferentes).Por ejemplo, una expresión regular escrita así:
Se convertirá en algo como esto:
No lo he usado mucho en la práctica, pero parece que funciona bien en mis pruebas, por lo que estoy publicando aquí en caso de que alguien lo encuentre útil. A pesar de la longitud de las expresiones regulares resultantes (el ejemplo anterior tiene 3591 caracteres cuando se expande), el rendimiento parece ser aceptable (ver las pruebas en jsFiddle; gracias a @modiX y @Lwangaman por las mejoras).
Aquí está la fuente (sin procesar, 27.5KB; minificada , 24.9KB, no mucho mejor ...). Se podría hacer más pequeña la representación no literal por los caracteres Unicode, pero otoh correrá el riesgo de problemas de codificación, así que estoy dejando tal cual es. Esperemos que con ES6 este tipo de cosas ya no sea necesario.
Actualización : esta parece la misma estrategia adoptada en el complemento XRegExp Unicode mencionado por Tim Down, excepto que en este caso se utilizan expresiones regulares de JavaScript.
fuente
/^\p{L}+$/
debería coincidir東海林
pero no. Cada vez que actualice la colección, infórmeme. Muchas gracias.\p{Lo}
, te pierdes las dos tablas Kanji.Como se menciona en otras respuestas, las expresiones regulares de JavaScript no son compatibles con las clases de caracteres Unicode. Sin embargo, hay una biblioteca que proporciona esto: el excelente XRegExp de Steven Levithan y su complemento Unicode .
fuente
[^\u0000-\u007F]+
para cualquier carácter que no esté incluido caracteres ASCII.Por ejemplo:
Aquí hay algunas referencias perfectas:
Generador RegExp de rango Unicode
Expresiones regulares Unicode
Gráficos de código de caracteres Unicode 10.0
Coincide con el rango de bloque Unicode
fuente
Septiembre de 2018 (actualizado en febrero de 2019)
Parece que regexp
/\p{L}/u
para letras de coincidencia (como categorías unicode )Aquí hay un ejemplo de trabajo.
Reporto este error aquí .
Actualizar
Después de más de 2 años de acuerdo con: 1500035 > 1361876 > 1634135 finalmente este error se corrigió y estará disponible en Firefox v.78 +
fuente
Esto lo hará:
Selecciona explícitamente un rango de caracteres unicode. Funcionará para los caracteres latinos, pero otros caracteres extraños pueden estar fuera de este rango.
fuente
\u0100
y\u0280
: muchos de ellos pueden considerarse caracteres latinos pero otros no: var s = ''; para (var i = 0xff; i <= 0x280; i ++) {s + = String.fromCharCode (i)} "ÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏ ... ǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀ"En JavaScript, \ w y \ d son ASCII, mientras que \ s es Unicode. No me preguntes por qué. JavaScript admite \ p con categorías Unicode, que puede usar para emular un \ wy \ d con reconocimiento Unicode.
Para \ d use \ p {N} (números)
Para \ w use [\ p {L} \ p {N} \ p {Pc} \ p {M}] (letras, números, guiones bajos, marcas)
Actualización: Desafortunadamente, me equivoqué sobre esto. JavaScript tampoco admite oficialmente \ p, aunque algunas implementaciones aún pueden admitir esto. El único soporte Unicode en expresiones regulares de JavaScript es hacer coincidir puntos de código específicos con \ uFFFF. Puede usarlos en rangos en clases de caracteres.
fuente
/\p{L}+/u
Si está utilizando Babel , el soporte Unicode ya está disponible.
También lancé un complemento que transforma su código fuente de manera que pueda escribir expresiones regulares como
/^\p{L}+$/
. Estos se transformarán en algo que los navegadores entiendan.Aquí está la página del proyecto del complemento:
babel-plugin-utf-8-regex
fuente
Estoy respondiendo a esta pregunta
¿Cuál sería el equivalente para \ p {Lu} o \ p {Ll} en regExp para js?
ya que se marcó como un duplicado exacto de la vieja pregunta actual.
Al consultar la base de datos UCD de Unicode 12, \ p {Lu} genera 1,788 puntos de código.
La conversión a UTF-16 produce la equivalencia de construcción de clase.
Es solo una cadena de caracteres de 4k y es fácilmente factible en cualquier motor de expresiones regulares.
Al consultar la base de datos UCD de Unicode 12, \ p {Ll} genera 2,151 puntos de código.
La conversión a UTF-16 produce la equivalencia de construcción de clase.
Tenga en cuenta que una implementación de expresiones regulares de \ p {Lu} o \ p {Pl} en realidad llama a un
función no estándar para probar el valor.
Las clases de caracteres que se muestran aquí se realizan de manera diferente y son lineales, estándar
y bastante lentas, cuando se agrupan principalmente en una sola clase.
Una idea de cómo un motor Regex (en general) implementa las clases de propiedad Unicode:
Examine estas características de rendimiento entre la propiedad
y el bloque de clase (como arriba)
¡Qué diferencia!
Veamos cómo se pueden implementar las Propiedades
Matriz de punteros [10FFFF] donde cada índice es un punto de código
Cada puntero en la matriz es a una estructura de clasificación.
Una estructura de clasificación contiene elementos de campo fijos.
Algunos son NULL y no pertenecen.
Algunos contienen clasificaciones de categoría.
Ejemplo: Categoría general
Este es un elemento de mapa de bits que utiliza 17 de 64 bits.
Lo que sea que admita este punto de código tiene los bits establecidos como una máscara.
-Close_Punctuation
-Connector_Punctuation
-Control
-Currency_Symbol
-Dash_Punctuation
-Decimal_Number
-Enclosing_Mark
-Final_Punctuation
-Formato
-Initial_Punctuation
-Letter_Number
-Line_Separator
-Lowercase_Letter
-Math_Symbol
-Modifier_Letter
-Modifier_Symbol
-Nonspacing_Mark
-Open_Punctuation
-Other_Letter
-Other_Number
-Other_Punctuation
-Other_Symbol
-Paragraph_Separator
-Private_Use
-Space_Separator -Sustituto
-Spacing_Mark
-Titlecase_Letter
-Unassigned
-Uppercase_Letter
Cuando una expresión regular se analiza con algo como esto \ p {Lu} se
traduce directamente a
Otro ejemplo, cuando una expresión regular se analiza con la propiedad de puntuación \ p {P},
se traduce a
Una comprobación de ese elemento para cualquiera de estos bits de elementos, que se unen en una máscara:
-Cierre_Punctuation
-Connector_Punctuation
-Dash_Punctuation
-Pinal_Punctuation
-Initial_Punctuation
-Open_Punctuation
-Other_Punctuation
El desplazamiento y el bit o bit (máscara) se almacenan como un paso de expresión regular para esa propiedad.
La tabla de búsqueda se crea una vez para todos los puntos de código Unicode que utilizan esta matriz.
Cuando se verifica un carácter, es tan simple como usar el CP como índice en esta matriz y verificar el elemento específico de la Estructura de clasificación para ese bit (máscara).
Esta estructura es expandible e indirecta para proporcionar búsquedas mucho más complejas. Este es solo un ejemplo simple.
Compare esa búsqueda directa con una búsqueda de clase de personaje:
Todas las clases son una lista lineal de elementos buscados de izquierda a derecha.
En esta comparación, dado que nuestra cadena de destino contiene solo las letras Unicode mayúsculas completas, la ley de los promedios predeciría que la mitad de los elementos de la clase tendrían que ser revisados para encontrar una coincidencia.
Esta es una gran desventaja en el rendimiento.
Sin embargo, si las tablas de búsqueda no están allí o no están actualizadas con la última versión de Unicode (12 a partir de esta fecha)
, esta sería la única forma.
De hecho, es principalmente la única forma de obtener los
caracteres Emoji completos , ya que no existe una propiedad (o razonamiento) específica para su asignación.
fuente
También puedes usar:
fuente