Obtener texto después de la cadena

Estoy buscando ayuda para crear una expresión regular que pueda obtener un determinado texto después de una cadena dada usando Python.

Estoy tratando de extraer un JSON de una página y es así:

var config = {aslkdjsakljdkalsj{asdasdas}askldjaskljd}; 

Necesito una expresión regular que pueda obtener desde la primera {hasta la} => sin el punto y coma

He intentado usar

  config = .*?(?=\}\;) 

pero la salida es

  config = {sadasdasdas{a}asdasdasd 

Obtiene la config = parte y no obtiene la última } .

¿Cómo puedo arreglarlo?

Si su línea de JS no está garantizada para contener caracteres de nueva línea antes de la terminación ; , entonces el problema es bastante simple: var config = coincidir var config = , seguido de los caracteres que no son de nueva línea capturados en un grupo, y luego haga un punto y coma al final de la línea. Si el JSON está delimitado con ' s, entonces, por ejemplo, use el patrón

 var config = '(.+)';$ 

y extraer el primer grupo.

 input = ''' var config = '{ "foo": "b\\ar", "ba{{}}}{{z": ["buzz}", "qux", {"innerprop": "innerval"}]}'; var someOtherVar = 'bar'; ''' match = re.search("(?m)var config = '(.+)';$", input); 

Si no se garantiza que JSON esté en su propia línea, entonces es mucho más complicado. Analizar estructuras anidadas como JSON es difícil: la única forma de solucionar el problema general es con expresiones regulares si la estructura se conoce de antemano (lo que a menudo no es el caso y puede requerir una gran cantidad de código repetitivo en el patrón), o si el motor RE que se está utilizando soporta coincidencias recursivas. Sin eso, no hay manera de express la necesidad de un número equilibrado de { s con } s en el patrón.

Afortunadamente, si está trabajando con Python, aunque los RE nativos de Python no son compatibles con la recursión, existe un módulo de expresiones regulares disponible. También deberá asegurarse de que las { y } s que pueden estar dentro de las cadenas en el JSON no afecten el nivel de anidamiento actual. Para una cadena en bruto, necesitarías un patrón como

 var config = String\.raw`\K({(?:"(?:\\|\\"|[^"])*"|[^{}]|(?1))*})(?=`;) 

El exterior del grupo de captura es

 var config = String\.raw`\K({ ... })(?=`;) 

que coincida con la línea que desea y los delimitadores de cadena, con un grupo de captura de

 {(?:"(?:\\|\\"|[^"])*"|[^{}]|(?1))*} 

lo que significa – { , seguido de cualquier número de:

  • "(?:\\|\\"|[^"])*" – coincide con una cadena dentro del JSON (ya sea una clave o un valor), desde su delimitador de inicio hasta su delimitador final, ignorando las " s " escapadas, o
  • [^{}] : Haga coincidir cualquier cosa que no sea un { o } – se pueden ignorar otros caracteres, ya que solo queremos obtener el nivel de anidación correcto, o
  • (?1) – Recurse todo el primer grupo de captura (el que coincide con el { ... } )

Esto asegurará que los corchetes { } estén equilibrados al final del patrón.


Pero, lo anterior es un ejemplo donde se usó String.raw , donde las barras invertidas literales en el código Javascript indican barras diagonales literales en la cadena. Con los ' delimitadores ' , por otra parte, las barras invertidas literales deben tener un doble escape en el JS, por lo que la entrada anterior se vería como

 var config = '{ "foo": "b\\\\ar", "ba{{}}}{{z": ["buzz}", "qux", {"innerprop": "innerval"}]}'; 

requiriendo doble escape de las barras invertidas en el patrón también:

 var config = '\K({(?:"(?:\\\\|\\\\"|[^"])*"|[^{}]|(?1))*})(?=';) 

https://regex101.com/r/8rSrGf/1

Es bastante complicado. Recomiendo ir con el primer enfoque o una variación en él, si es posible.