standard spec javascript regex

javascript - standard - html spec



¿Hay un caso donde "[^ xy]" no es igual a "(?! X | y)."? (5)

Estoy trabajando en mi propia biblioteca de JavaScript para admitir nuevos metacaracteres y funciones para expresiones regulares, y me gustaría encontrar un caso donde [^xy] no sea equivalente a (?!x). (o más específicamente (?:(?!x|y).) ).

Toma el texto de ejemplo: "abc/n"

Digamos que quiero emular una expresión regular de Perl: //A.{3}/Z/s

Con el indicador de línea simple, la expresión regular de JavaScript debe ser equivalente a: /^[/s/S]{3}/n*$(?!/s)/ ( /A convierte en ^ /A convierte en [/s/S] , /Z convierte en /n*$(?!/s) )

Ahora, /^.{3}$/ fallaría, pero /^[/s/S]{3}/n*$(?!/s)/ capturaría "abcabc" (igual que la expresión regular de Perl)

Como /Z contiene más que solo un metacarácter, emular [^/Z] parece ser más difícil.

Tome el texto de ejemplo: "abcabc/n"

La propuesta de expresión regular de JavaScript para Perl regex /.{3}[^/Za]/g sería .{3}(?:(?!/n*$(?!/s)|a).)/g

Ambos coincidirán con "bcab"

Así que, finalmente, vuelvo a plantear la pregunta. ¿Existe un caso en el que [^xy] no sea equivalente a (?:(?!x|y).) Con ese escenario, tal vez en una expresión regular más compleja donde un lookahead cambiaría el escenario?


¿Hay algún caso en el que [^xy] no sea igual a (?!x|y). ?

Solo el que ya ha descrito: el punto JS no coincide con las líneas nuevas y debe reemplazarse con [/s/S] .

/Z convierte en /n$(?!/s)

Eso se ve mal. Después del final de la cadena ( /z / $ ) nunca habrá nada, independientemente de si hay espacios en blanco o no. Afaik, /Z es una aserción de ancho cero (no consume las nuevas líneas) y debe ser equivalente a

(?=/n*$) // ^ not sure whether ? or *

Como /Z contiene más que solo un metacarácter, emular [^/Z] parece ser más difícil.

¿Qué quieres decir con "metacarácter"? Es una aserción de ancho cero, y no tiene mucho sentido en una clase de personaje. Supongo que es un error de sintaxis o se interpretará literalmente (sin escapar) como [^Z] .


Como dijeron los demás, debes usar [/s/S] lugar de . En el reemplazo. De lo contrario, si está haciendo esa transformación solo a través de las cadenas literales, hay algunas cosas más que cuidar. En particular, los meta caracteres y las secuencias de escape:

[^*)] => (?!/*|/))[/s/S]

Pero supongo que tendrás que ocuparte del análisis y la escritura de los metacaracteres de todos modos.

Sin embargo, el más complicado es probablemente /b , porque es un carácter (retroceso) en las clases de caracteres y un límite de palabra fuera. Así que en el reemplazo, tendrías que ir con un escape octal o hexadecimal:

[^a/b] => (?!a|/10)[/s/S] or => (?!a|/x08)[/s/S]

Aparte de eso, los dos siempre deben ser equivalentes.


Para la cadena de entrada "x/na" , las 2 expresiones regulares dan diferentes salidas, porque . no coincide con las nuevas líneas.

console.log("x/na".match(/(?:(?!x|y).)/)) ["a", index: 2, input: "x↵a"] console.log("x/na".match(/[^xy]/)) ["↵", index: 1, input: "x↵a"]

Si cambias . para [/s/S] , la salida es idéntica en este caso:

console.log("x/na".match(/(?:(?!x|y)[/s/S])/)) ["↵", index: 1, input: "x↵a"]

No puedo pensar en ningún otro caso en este momento.


Un caso donde el formato [^xy] no es el mismo que (?:(?!x|y).) Sería donde x fue una aserción de ancho cero en lugar de un carácter real como:

Dado este texto de muestra: ab-yz

Regex: [^/by] Ejemplo: http://www.rubular.com/r/ERKrqyeAs9

Devoluciones:

[0] => a [1] => b [2] => - [3] => z

Mientras

Regex: (?:(?!/b|y).) Ejemplo: http://www.rubular.com/r/V5RdyQEQo5

Devoluciones:

[0] => b [1] => z

Otras expresiones no equivalentes, se enfocan principalmente en el hecho de que la misma sintaxis tiene diferentes elementos dentro o fuera de la clase de caracteres:

  • [^^y] produce a, b, -, z no es igual a (?:(?!^|y).) produce b, -, z
  • [^.y] produce a, b, -, z no es igual a (?:(?!.|y).) no produce nada

O puedes intentar esto en un nugget Unicode en Perl: http://ideone.com/2xMfkQ

print "/ncapture/n"; @m = ("ss" =~ m/^(?:(?!/xDF|y).)+$/ui ); print for @m; print "/nclass/n"; @m = ("ss" =~ m/^[^/xDFy]+$/ui) ; print for @m;

Rendimientos:

capture class 1


[^xy] coincidirá con /n . (?!x|y). no coincidirá con /n por defecto (porque . no coincide con /n )

No creo que javascript tenga un modificador "dotall" o "single-line", pero con nuevas versiones de cada navegador cada dos meses, he perdido la pista.