Tengo la siguiente cadena:
"Hola, no coincida con esto: !{SUM(1,2)}" sino con esto: !{SUM(1,2)} "Y no con esto: !{MEAN(3,4)}"
Actualmente tengo la siguiente expresión regular (\!{(?:\[??[^\[]*?\})) para que coincida con todos !{}
¿Cómo podría agregar a esto para que coincida con todos los !{.} que NO están dentro de un par de comillas dobles?
No estoy seguro de si esto es posible, ya que la sección central técnicamente estaría entre 2 comillas dobles.
¡¡Gracias por cualquier ayuda!!
https://regex101.com/r/QAmbym/1
^(?>".*"|[^!{}])*\K!{.*}
^ - Ancla al inicio de la cadena. Esto es importante debido a lo que sigue.
(?> - grupo atómico. una vez emparejado, no retroceda.
".*" - Consume cualquier cosa entre comillas. Una vez consumido, el motor no dará marcha atrás.
| - o
[^!{}] : haga coincidir cualquier cosa que no sea los caracteres que nos interesan. Estos siguen siendo parte del grupo atómico, por lo que no se puede hacer coincidir nada consumido.
)* - Cierra el grupo atómico y empareja todo el grupo 0 o más veces.
\K - restablecer el patrón. Deseche todo lo que coincida hasta este punto.
!{.*} - Lo que estás buscando.
Entonces, debido a que comenzamos anclados, consumiremos cualquier cosa que esté entre comillas o que definitivamente no sea lo que queremos. Se consume de una manera que no permitirá que el motor retroceda. Luego, una vez que llegamos a lo que estamos buscando, lo tiramos todo. Esto significa que cualquier cosa entre comillas no coincidirá.
Editar:
Gracias a que @Nick publicó el enlace al otro hilo, descubrí que hay una manera mucho más simple de hacerlo que funciona con javascript:
https://regex101.com/r/Y3QHTc/1
".*"|(!{.*})
".*" coincide con cualquier cosa entre comillas, sin agrupar
| o
(!{.*}) coincide con lo que está buscando en el grupo 1.
Si bien técnicamente está haciendo coincidir cadenas no deseadas, puede filtrar todo lo que no devuelve un grupo 1, dejándolo con lo que está buscando.
Dado que los grupos atómicos no son compatibles con JS, puede probar este método simple:
let s = `"Hello, don't match this: !{SUM(1,2)}" but match this: !{SUM(1,2)} "And not this: !{MEAN(3,4)}"` let pattern = /!{.+}/gm if (pattern.test(s.replaceAll(/".+?"/gm, ''))) { console.log("Match") } else { console.log("Not match") } Aquí s.replaceAll(/".+?"/gm, '') te da: but match this: !{SUM(1,2)}
luego aplica el patrón !{.+} para que coincida con todo lo que está entre !{ y } , en él.