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] .
/Zconvierte 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
/Zcontiene 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.