En qué se equivocó la API RegExp de JavaScript y cómo solucionarlo

En los últimos años, ocasionalmente he comentado sobre la API RegExp de JavaScript, la sintaxis y el comportamiento en la lista de correo ES-Discuss. Recientemente, el inventor de JavaScript, Brendan Eich, sugirió que, para que haya más discusión, escriba una lista de cambios de expresiones regulares a considerar para futuros estándares de ECMAScript (o, como lo expresó con humor, tener mis "95 [regex] tesis clavadas en el puerta de catedral ES3"). Pensé que le daría una oportunidad, pero voy a dividir mi respuesta en algunas partes. En esta publicación, analizaré los problemas con la API RegExp actual y el comportamiento. Dejaré de lado las nuevas funciones que me gustaría ver agregadas y simplemente sugeriré formas de mejorar las capacidades existentes. Hablaré sobre posibles funciones nuevas en una publicación de seguimiento.

Para un lenguaje tan ampliamente utilizado como JavaScript, cualquier propuesta de cambio realista debe considerar seriamente la compatibilidad con versiones anteriores. Por esta razón, algunas de las siguientes propuestas podrían no ser particularmente realista, pero sin embargo creo que a ) vale la pena considerar qué podría cambiar si la compatibilidad con versiones anteriores no fuera una preocupación, y b ) a largo plazo, todos estos cambios mejorarían la facilidad de uso y la previsibilidad de cómo funcionan las expresiones regulares en JavaScript.

Elimine RegExp.prototype.lastIndex y reemplácelo con un argumento para la posición de inicio

Propuesta real:obsoleto RegExp.prototype.lastIndex y agregue un argumento "pos" a los métodos RegExp.prototype.exec/test

08 de JavaScript la propiedad sirve para demasiados propósitos a la vez:

Permite a los usuarios especificar manualmente dónde iniciar una búsqueda de expresiones regulares
Podría afirmar que esto no es 11 es el propósito previsto, pero sin embargo es un uso importante ya que no hay una función alternativa que lo permita. 23 aunque no es muy bueno en esta tarea. Debe compilar su expresión regular con el 30 bandera para dejar 40 ser usado de esta manera; e incluso entonces, solo especifica la posición inicial para el 57 /65 métodos. No se puede usar para establecer la posición de inicio para el 70 /84 /97 /109 métodos.
Indica la posición donde terminó el último partido
Aunque podría derivar la posición final de la coincidencia agregando el índice y la longitud de la coincidencia, este uso de 116 sirve como un complemento conveniente y de uso común para el 129 propiedad en arreglos coincidentes devueltos por 136 . Como siempre, usando 147 así funciona solo para expresiones regulares compiladas con 152 .
Se utiliza para rastrear la posición donde debería comenzar la próxima búsqueda
Esto entra en juego, por ejemplo, cuando se usa una expresión regular para iterar sobre todas las coincidencias en una cadena. Sin embargo, el hecho de que 160 en realidad se establece en la posición final de la última coincidencia en lugar de la posición donde debería comenzar la próxima búsqueda (a diferencia de los equivalentes en otros lenguajes de programación) causa un problema después de las coincidencias de longitud cero, que son fácilmente posibles con expresiones regulares como 179 o 188 . Por lo tanto, está obligado a incrementar manualmente 192 en esos casos. He publicado sobre este problema con más detalle antes (ver:Un error de IE lastIndex con coincidencias Regex de longitud cero ), al igual que Jan Goyvaerts (Cuidado con los partidos de duración cero ).

Desafortunadamente, 201 La versatilidad de da como resultado que no funcione idealmente para ningún uso específico. Creo que 215 está fuera de lugar de todos modos; si necesita almacenar la posición final (o el próximo inicio) de una búsqueda, debe ser una propiedad de la cadena de destino y no la expresión regular. Aquí hay tres razones por las que esto funcionaría mejor:

  • Te permitiría usar la misma expresión regular con varias cadenas, sin perder la pista de la siguiente posición de búsqueda dentro de cada una.
  • Permitiría usar múltiples expresiones regulares con la misma cadena y hacer que cada una continúe donde la dejó la última.
  • Si busca dos cadenas con la misma expresión regular, probablemente no espere que la búsqueda dentro de la segunda cadena comience desde una posición arbitraria solo porque se encontró una coincidencia en la primera cadena.

De hecho, Perl utiliza este enfoque de almacenar posiciones de búsqueda siguiente con cadenas con gran efecto, y agrega varias funciones a su alrededor.

Ese es mi caso para 220 estar fuera de lugar, pero voy más allá en que no creo que 234 debe incluirse en JavaScript en absoluto. La táctica de Perl funciona bien para Perl (especialmente cuando se considera como un paquete completo), pero algunos otros lenguajes (incluido Python) le permiten proporcionar una posición de inicio de búsqueda como argumento al llamar a los métodos de expresiones regulares, que creo que es un enfoque más natural. y más fácil de entender y usar para los desarrolladores. Por lo tanto, arreglaría 246 deshaciéndose de él por completo. Los métodos Regex y los métodos de cadena que usan expresiones regulares utilizarían rastreadores de posición de búsqueda internos que el usuario no puede observar, y el 255 y 267 los métodos obtendrían un segundo argumento (llamado 278 , por posición) que especifica dónde comenzar su búsqueda. Puede ser conveniente dar también el 280 métodos 295 , 305 , 317 y 329 su propio 338 argumentos, pero eso no es tan importante y la funcionalidad que proporcionaría no es posible actualmente a través de 343 de todos modos.

Los siguientes son ejemplos de cómo algunos usos comunes de 356 podría reescribirse si se hicieran estos cambios:

Inicie la búsqueda desde la posición 5, usando 360 (el estado de cosas):

var regexGlobal = /\w+/g,
    result;

regexGlobal.lastIndex = 5;
result = regexGlobal.test(str);
// must reset lastIndex or future tests will continue from the
// match-end position (defensive coding)
regexGlobal.lastIndex = 0;

var regexNonglobal = /\w+/;

regexNonglobal.lastIndex = 5;
// no go - lastIndex will be ignored. instead, you have to do this
result = regexNonglobal.test(str.slice(5));

Inicie la búsqueda desde la posición 5, usando 374 :

var regex = /\w+/, // flag /g doesn't matter
    result = regex.test(str, 5);

Coincidir iteración, usando 387 :

var regex = /\w*/g,
    matches = [],
    match;

// the /g flag is required for this regex. if your code was provided a non-
// global regex, you'd need to recompile it with /g, and if it already had /g,
// you'd need to reset its lastIndex to 0 before entering the loop

while (match = regex.exec(str)) {
    matches.push(match);
    // avoid an infinite loop on zero-length matches
    if (regex.lastIndex == match.index) {
        regex.lastIndex++;
    }
}

Iteración de coincidencia, usando 396 :

var regex = /\w*/, // flag /g doesn't matter
    pos = 0,
    matches = [],
    match;

while (match = regex.exec(str, pos)) {
    matches.push(match);
    pos = match.index + (match[0].length || 1);
}

Por supuesto, podría agregar fácilmente su propio azúcar para simplificar aún más la iteración de coincidencias, o JavaScript podría agregar un método dedicado a este propósito similar al 404 de Ruby. (aunque JavaScript ya tiene esto mediante el uso de funciones de reemplazo con 410 ).

Para reiterar, estoy describiendo lo que haría si la compatibilidad con versiones anteriores fuera irrelevante. No creo que sea una buena idea agregar un 422 argumento del 432 y 442 métodos a menos que el 453 La propiedad quedó en desuso o se eliminó debido a la superposición de funciones. Si un 460 existía el argumento, la gente esperaría 479 ser 480 cuando no se especifica. Tener 496 dar vueltas para arruinar a veces esta expectativa sería confuso y probablemente conduciría a errores latentes. Por lo tanto, si 508 fue obsoleto a favor de 518 , debería ser un medio hacia el final de la eliminación de 521 en total.

Eliminar el modo operativo no global de String.prototype.match

Propuesta real:dejar de usar String.prototype.match y agregar un nuevo método matchAll

532 actualmente funciona de manera muy diferente dependiendo de si el 543 El indicador (global) se ha establecido en la expresión regular proporcionada:

  • Para expresiones regulares con 551 :Si no se encuentran coincidencias, 566 es regresado; de lo contrario, se devuelve una matriz de coincidencias simples.
  • Para expresiones regulares sin 579 :El 587 El método opera como un alias de 594 . Si no se encuentra una coincidencia, 601 es regresado; de lo contrario, obtiene una matriz que contiene la coincidencia (única) en la clave cero, con cualquier referencia inversa almacenada en las claves posteriores de la matriz. A la matriz también se le asigna un 611 especial y 625 propiedades.

El 631 el modo no global del método es confuso e innecesario. La razón por la que no es necesario es obvia:si desea la funcionalidad de 642 , simplemente utilícelo (no es necesario un alias). Es confuso porque, como se describió anteriormente, el 654 Los dos modos del método devuelven resultados muy diferentes. La diferencia no es simplemente si obtiene una coincidencia o todas las coincidencias:obtiene un tipo de resultado completamente diferente. Y dado que el resultado es una matriz en cualquier caso, debe conocer el estado del 666 de la expresión regular propiedad para saber con qué tipo de matriz está tratando.

Yo cambiaría 670 haciendo que siempre devuelva una matriz que contenga todas las coincidencias en la cadena de destino. También haría que devuelva una matriz vacía, en lugar de 683 , cuando no se encuentran coincidencias (una idea que proviene de la biblioteca base2 de Dean Edwards). Si solo desea la primera coincidencia o necesita referencias anteriores y detalles adicionales de la coincidencia, eso es lo que 690 es para.

Desafortunadamente, si desea considerar este cambio como una propuesta realista, requeriría algún tipo de versión de idioma o cambio de modo basado en el 708 el comportamiento del método (es poco probable que suceda, creo). Entonces, en lugar de eso, recomendaría desaprobar el 713 método en conjunto a favor de un nuevo método (quizás 727 ) con los cambios prescritos anteriormente.

Deshágase de /g y RegExp.prototype.global

Propuesta real:Desechar /g y RegExp.prototype.global, y agregar un argumento booleano replaceAll a String.prototype.replace

Si las dos últimas propuestas fueran implementadas y por lo tanto 737 y 742 eran cosas del pasado (o 759 ya no sirve a veces como un alias de 762 ), el único método donde 779 todavía tendría algún impacto es 780 . Además, aunque 795 sigue el estado de la técnica de Perl, etc., realmente no tiene sentido tener algo que no sea un atributo de una expresión regular almacenado como un indicador de expresión regular. De verdad, 800 es más una declaración sobre cómo desea que los métodos apliquen su propia funcionalidad, y no es raro querer usar el mismo patrón con y sin 812 (actualmente tendría que construir dos expresiones regulares diferentes para hacerlo). Si fuera por mí, me desharía del 821 flag y su correspondiente 835 propiedad, y en su lugar simplemente da el 844 método un argumento adicional que indica si desea reemplazar solo la primera coincidencia (el manejo predeterminado) o todas las coincidencias. Esto podría hacerse con un 859 booleano o, para mayor legibilidad, un 863 cadena que acepta valores 878 y 886 . Este nuevo argumento tendría el beneficio adicional de permitir la funcionalidad de reemplazar todo con búsquedas sin expresiones regulares.

Tenga en cuenta que SpiderMonkey ya tiene un tercer propietario 895 argumento ("banderas") con el que esta propuesta entraría en conflicto. Dudo que este conflicto cause mucha acidez estomacal, pero en cualquier caso, un nuevo 908 argumento proporcionaría la misma funcionalidad que el 911 de SpiderMonkey El argumento es más útil para (es decir, permitir reemplazos globales con búsquedas que no son expresiones regulares).

Cambiar el comportamiento de las referencias inversas a grupos no participantes

Propuesta real:hacer que las referencias inversas a grupos no participantes no coincidan

Seré breve, ya que David "liorean" Andersson y yo hemos defendido esto anteriormente en ES-Discuss y en otros lugares. David publicó esto en detalle en su blog (ver:ECMAScript 3 Expresiones regulares:una especificación que no tiene sentido ), y ya lo mencioné anteriormente aquí (ECMAScript 3 Regular Expressions are Defective by Design ). En varias ocasiones, Brendan Eich también ha declarado que le gustaría que esto cambiara. La breve explicación de este comportamiento es que, en JavaScript, las referencias inversas a la captura de grupos que (todavía) no han participado en una coincidencia siempre tienen éxito (es decir, coinciden con la cadena vacía), mientras que ocurre lo contrario en todos los demás tipos de expresiones regulares:no coinciden y, por lo tanto, hacen que el motor de expresiones regulares retroceda o falle. El comportamiento de JavaScript significa que 924 devuelve 938 . Las implicaciones (negativas) de esto llegan bastante lejos cuando se amplían los límites de las expresiones regulares.

Creo que todos están de acuerdo en que cambiar al comportamiento tradicional de referencias inversas sería una mejora:proporciona un manejo mucho más intuitivo, compatibilidad con otros tipos de expresiones regulares y un gran potencial para el uso creativo (por ejemplo, vea mi publicación sobre Mimicking Conditionals ). La pregunta más importante es si sería seguro, a la luz de la compatibilidad con versiones anteriores. Creo que lo sería, ya que me imagino que más o menos nadie usa el comportamiento poco intuitivo de JavaScript intencionalmente. El comportamiento de JavaScript equivale a agregar automáticamente un 945 cuantificador después de las referencias inversas a grupos no participantes, que es lo que las personas ya hacen explícitamente si realmente quieren que las referencias inversas a subpatrones de longitud distinta de cero sean opcionales. También tenga en cuenta que Safari 3.0 y versiones anteriores no siguieron la especificación en este punto y utilizaron un comportamiento más intuitivo, aunque eso ha cambiado en versiones más recientes (en particular, este cambio se debió a un artículo en mi blog en lugar de informes de real- errores mundiales).

Finalmente, probablemente valga la pena señalar que el modo de expresiones regulares ECMAScript de .NET (habilitado a través del 957 flag) de hecho cambia .NET al comportamiento de referencia inversa no convencional de ECMAScript.

Hacer que \d \D \w \W \b \B sea compatible con Unicode (como \s \S . ^ $, que ya lo son)

Propuesta real:Agregar un indicador /u (y la propiedad RegExp.prototype.unicode correspondiente) que cambia el significado de \d, \w, \b y tokens relacionados

La coincidencia de caracteres de palabras y dígitos con reconocimiento de Unicode no es una capacidad existente de JavaScript (salvo que se construyan monstruosidades de clases de caracteres que tengan cientos o miles de caracteres), y dado que JavaScript carece de mirar atrás, no puede reproducir un límite de palabras con reconocimiento de Unicode. Por lo tanto, podría decir que esta propuesta está fuera del alcance declarado de esta publicación, pero la incluyo aquí porque considero que es más una solución que una nueva función.

De acuerdo con los estándares actuales de JavaScript, 962 , 971 , 986 , 997 y 1003 usar interpretaciones basadas en Unicode de espacios en blanco y nueva línea , mientras que 1017 , 1028 , 1030 , 1048 , 1054 y 1065 usar interpretaciones solo ASCII de dígito , carácter de palabra y límite de palabra (por ejemplo, 1075 lamentablemente devuelve 1085 ). Vea mi publicación sobre JavaScript, Regex y Unicode para mas detalles. Agregar compatibilidad con Unicode a estos tokens provocaría un comportamiento inesperado en miles de sitios web, pero podría implementarse de manera segura a través de un nuevo 1096 bandera (inspirada en 1101 de Python o 1112 flag) y un 1123 correspondiente propiedad. Dado que en realidad es bastante común no desea que estos tokens estén habilitados para Unicode en patrones de expresiones regulares particulares, una nueva bandera que active la compatibilidad con Unicode ofrecería lo mejor de ambos mundos.

Cambiar el comportamiento del restablecimiento de la referencia inversa durante la repetición del subpatrón

Propuesta real:nunca restablecer los valores de referencia inversa durante una coincidencia

Al igual que el último problema de referencias inversas, esto también lo trató David Andersson en su publicación Expresiones regulares de ECMAScript 3:una especificación que no tiene sentido . El problema aquí involucra el valor recordado al capturar grupos anidados dentro de un grupo externo cuantificado (por ejemplo, 1139 ). De acuerdo con el comportamiento tradicional, el valor recordado por un grupo de captura dentro de una agrupación cuantificada es lo que el grupo acertó la última vez que participó en el partido. Entonces, el valor de 1142 después de 1151 se utiliza para coincidir con 1165 sería 1175 . Sin embargo, según ES3/ES5, el valor de las referencias anteriores a agrupaciones anidadas se restablece/borra después de que se repite la agrupación externa. Por lo tanto, 1186 todavía coincidiría con 1194 , pero después de que se complete la coincidencia 1209 haría referencia a un grupo de captura no participante, que en JavaScript coincidiría con una cadena vacía dentro de la propia expresión regular y se devolvería como 1212 en, por ejemplo, la matriz devuelta por el 1220 .

Mi argumento a favor del cambio es que el comportamiento de JavaScript actual se sale de la norma en otros tipos de expresiones regulares, no se presta a varios tipos de patrones creativos (vea un ejemplo en mi publicación sobre Captura de múltiples valores de atributos HTML opcionales ) y, en mi opinión, es mucho menos intuitivo que el comportamiento alternativo de expresiones regulares más común.

Creo que es seguro cambiar este comportamiento por dos razones. En primer lugar, este es generalmente un problema de caso extremo para todos los asistentes de expresiones regulares, excepto para los más duros, y me sorprendería encontrar expresiones regulares que dependan de la versión de JavaScript de este comportamiento. En segundo lugar, y más importante, Internet Explorer no implementa esta regla y sigue el comportamiento más tradicional.

Agregue una bandera /s, ya

Propuesta real:agregar un indicador /s (y la propiedad RegExp.prototype.dotall correspondiente) que cambia el punto para que coincida con todos los caracteres, incluidas las líneas nuevas

Introduciré esta como un cambio/corrección en lugar de una nueva función, ya que no es exactamente difícil de usar 1237 en lugar de un punto cuando desea el comportamiento de 1244 . Supongo que el 1254 flag se ha excluido hasta ahora para salvar a los novatos de sí mismos y limitar el daño del retroceso descontrolado, pero lo que termina sucediendo es que las personas escriben patrones horriblemente ineficientes como 1268 en su lugar.

Las búsquedas de expresiones regulares en JavaScript rara vez se basan en líneas y, por lo tanto, es más común querer que el punto incluya líneas nuevas que que coincida con cualquier cosa menos líneas nuevas (aunque ambos modos son útiles). Tiene sentido mantener el significado predeterminado de punto (sin saltos de línea) ya que es compartido por otros tipos de expresiones regulares y es necesario para la compatibilidad con versiones anteriores, pero agrega soporte para el 1274 la bandera está atrasada. Un valor booleano que indica si se configuró este indicador debería aparecer en las expresiones regulares como una propiedad denominada 1285 (el desafortunado nombre de Perl, .NET, etc.) o el más descriptivo 1297 (utilizado en Java, Python, PCRE, etc.).

Preferencias personales

Los siguientes son algunos cambios que se adaptarían a mis preferencias, aunque no creo que la mayoría de la gente los considere problemas importantes:

  • Permitir que los literales regex usen barras diagonales sin escape dentro de las clases de caracteres (p. ej., 1307 ). Esto ya estaba incluido en las propuestas de cambio de ES4 abandonadas.
  • Permitir un 1313 sin escape como el primer carácter en las clases de caracteres (por ejemplo, 1326 o 1331 ). Esto está permitido probablemente en todos los demás tipos de expresiones regulares, pero crea una clase vacía seguida de un literal 1341 en JavaScript. Me gustaría imaginar que nadie usa clases vacías intencionalmente, ya que no funcionan de manera consistente en varios navegadores y existen alternativas ampliamente utilizadas/de sentido común (1356 en lugar de 1368 y 1370 en lugar de 1386 ). Desafortunadamente, la adherencia a esta peculiaridad de JavaScript se prueba en Acid3 (prueba 89), lo que es lo suficientemente probable como para eliminar las solicitudes de este cambio razonable pero incompatible con versiones anteriores.
  • Cambiar el 1399 token usado en cadenas de reemplazo a 1405 . Simplemente tiene sentido. (Equivalentes en otros tipos de texto de reemplazo para comparar:Perl:1410; Java:1423; .NET:1438 , 1443; PHP:1456 , 1464; Rubí:1478 , 1485; Pitón:1499 .)
  • Deshágase del significado especial de 1506 . Dentro de las clases de caracteres, la metasecuencia 1518 coincide con un carácter de retroceso (equivalente a 1529 ). Esta es una conveniencia inútil ya que a nadie le importa hacer coincidir los caracteres de retroceso, y es confuso dado que 1538 coincide con un límite de palabra cuando se usa fuera de las clases de caracteres. Aunque esto rompería con la tradición de las expresiones regulares (que normalmente recomendaría seguir), creo que 1541 no debería tener un significado especial dentro de las clases de caracteres y simplemente coincidir con un literal 1554 .

Corregido en ES3:eliminar referencias de caracteres octales

ECMAScript 3 eliminó las referencias de caracteres octales de la sintaxis de expresiones regulares, aunque 1567 se mantuvo como una excepción conveniente que permite hacer coincidir fácilmente un carácter NUL. Sin embargo, los navegadores generalmente han mantenido el soporte octal completo para la compatibilidad con versiones anteriores. Los octales son muy confusos en las expresiones regulares, ya que su sintaxis se superpone con las referencias inversas y se permite un cero inicial adicional fuera de las clases de caracteres. Considere las siguientes expresiones regulares:

  • 1578 :1589 es un octal.
  • 1590 :1605 es una referencia inversa.
  • 1614 :1620 es un octal.
  • 1630 :1646 es una referencia inversa; 1657 es un octal.
  • 1661 :Todas las apariciones de 1673 y 1681 son octales. Sin embargo, de acuerdo con las especificaciones de ES3+, los números después de cada 1697 deben tratarse (salvo extensiones no estándar) como caracteres literales, cambiando por completo lo que coincide con esta expresión regular. (Edit-2012:En realidad, una lectura atenta de la especificación muestra que cualquier 0-9 después de 1706 debería causar un 1716 .)
  • 1726 :El 1737 fuera de la clase de caracteres es un octal; pero adentro, el octal termina en el tercer cero (es decir, la clase de carácter coincide con el índice de carácter cero o 1744 ). Por lo tanto, esta expresión regular es equivalente a 1755; aunque, como se mencionó anteriormente, la adhesión a ES3 cambiaría el significado.
  • 1766 :Fuera de la clase de caracteres, el octal termina en el cuarto cero y va seguido de un literal 1770 . En el interior, el octal termina en el tercer cero y va seguido de un literal 1785 . Y una vez más, la exclusión de octales de ES3 y la inclusión de 1795 podría cambiar el significado.
  • 1808 :dado que, en JavaScript, las referencias inversas a grupos de captura que (todavía) no han participado coinciden con la cadena vacía, ¿esta expresión regular coincide con 1816? (es decir, 1826 se trata como una referencia inversa ya que aparece un grupo de captura correspondiente en la expresión regular) o coincide con 1835 (es decir, el 1849 se trata como un octal ya que aparece antes su grupo correspondiente)? Como era de esperar, los navegadores no están de acuerdo.
  • 1855 :Ahora las cosas se ponen realmente peludas. ¿Esta expresión regular coincide con 1861? , 1871 , 1887 , 1895 , 1909 o 1917 ? Todas estas opciones parecen plausibles y los navegadores no están de acuerdo sobre la elección correcta.

También hay otros problemas de los que preocuparse, como si los escapes octales suben a 1925 (1938 , 8 bits) o 1940 (1957 , 9 bits); pero en cualquier caso, los octales en las expresiones regulares son un grupo confuso. Aunque ECMAScript ya ha solucionado este problema al eliminar la compatibilidad con octales, los navegadores no han seguido su ejemplo. Me gustaría que lo hicieran, porque a diferencia de los fabricantes de navegadores, no tengo que preocuparme por este legado (nunca uso octales en expresiones regulares, y tú tampoco deberías).

Corregido en ES5:no almacenar en caché los literales de expresiones regulares

De acuerdo con las reglas de ES3, los literales de expresiones regulares no creaban un nuevo objeto de expresión regular si ya se usaba un literal con la misma combinación de patrón/marca en el mismo script o función (esto no se aplicaba a las expresiones regulares creadas por 1966 constructor). Un efecto secundario común de esto fue que los literales de expresiones regulares que usaban 1974 bandera no tenía su 1984 restablecimiento de propiedad en algunos casos donde la mayoría de los desarrolladores lo esperarían. Varios navegadores no siguieron las especificaciones de este comportamiento poco intuitivo, pero Firefox sí lo hizo y, como resultado, se convirtió en el segundo informe de error de JavaScript más duplicado para Mozilla. Afortunadamente, ES5 se deshizo de esta regla, y ahora los literales regex deben volver a compilarse cada vez que se encuentran (este cambio se realizará en Firefox 3.7).

———
Así que ahí lo tienes. He esbozado lo que creo que la API RegExp de JavaScript se equivocó. ¿Está de acuerdo con todas estas propuestas, o estaría ¿No tendrías que preocuparte por la compatibilidad con versiones anteriores? ¿Existen formas mejores que las que he propuesto para solucionar los problemas que se tratan aquí? ¿Tienes alguna otra queja con las funciones de expresiones regulares de JavaScript existentes? Estoy ansioso por escuchar comentarios sobre esto.

Dado que me he centrado en lo negativo de esta publicación, notaré que encuentro que trabajar con expresiones regulares en JavaScript es una experiencia generalmente agradable. Hay muchas cosas que JavaScript acertó.