¿Por qué las expresiones regulares creadas con el generador de expresiones regulares usan una sintaxis diferente de las expresiones regulares interactivas?

26

Entonces, usando el generador de expresiones regulares (Mx re-builder), encontrar líneas que terminan en \ toma "\\ $", mientras que en la búsqueda y reemplazo por expresión regular, solo toma "\ $". Hubiera esperado que el generador de expresiones regulares construyera expresiones directamente utilizables, entonces, ¿qué explica esta diferencia?

usuario2699
fuente
66
Construye expresiones directamente utilizables en código.
abo-abo
1
@ abo-abo Esa es la respuesta que estaba buscando, no me di cuenta de que hay una diferencia entre lo que se puede usar en el código y lo que se puede usar en la interfaz de usuario. Parece contrario a la intuición que el reconstructor utiliza la sintaxis de códigos, y el manual no dice, pero eso explica la diferencia.
user2699
2
Para hacer que el generador de expresiones regulares sea más útil para componer búsquedas interactivas, eche un vistazo a la página wiki ReBuilder emacs , especialmente la reb-query-replacedefinición de la función.
dfeich

Respuestas:

29

En realidad, hay cuatro re-builderopciones de sintaxis diferentes , y puede cambiar entre ellas conC-cTAB

Dos son para los compiladores de expresiones regulares sexp-form rxy sregex(pero como el primero es más completo y casi totalmente compatible con la sintaxis, realmente puede ignorar sregex a menos que esté trabajando con el código antiguo que lo usó).

Las otras dos opciones de sintaxis son read(la predeterminada) y string(que es la sintaxis que usa de forma interactiva).

La readsintaxis es la sintaxis de 'código', es decir, tal como lo reconoce el lector de lisp, en la que se ingresa la expresión regular según la sintaxis de lectura para las cadenas :

C-hig (elisp) Syntax for Strings RET

La stringsintaxis (que siempre he considerado un nombre innecesariamente confuso en este contexto) es la sintaxis de una cadena de expresión regular que ya se ha leído y que, por lo tanto, no requiere que se escape ningún carácter al escribir la cadena. Es decir, esta es la sintaxis de expresión regular real , la misma que usa cuando Emacs le solicita interactivamente.

Si desea utilizar la sintaxis de cadena de forma predeterminada, agregue lo siguiente a su archivo de inicio o use M-x customize-option RET reb-re-syntax RET

(setq reb-re-syntax 'string)

Tenga en cuenta que puede alternar entre la sintaxis de lectura y cadena al editar la expresión regular, sin pérdida de datos. También puede cambiar de los formularios sexp a la sintaxis de lectura / cadena (naturalmente; compilar sexps en cadenas es para lo que sirven esas bibliotecas), pero no puede ir en la otra dirección y generar un sexp a partir de una cadena. re-builder recuerda cuál era el sexp, por lo que no pierde esa forma cuando cambia la sintaxis; pero tampoco se actualiza si modifica la expresión regular en una sintaxis diferente y luego cambia de nuevo. En resumen, si está creando la expresión regular como sexp, asegúrese de editarla solo mientras usa esa sintaxis.


Un problema con el rxsoporte es que en realidad está usando la rx-to-stringfunción, que no es exactamente idéntica a usar la rxmacro en el código. rxacepta un número arbitrario de argumentos de forma y los trata como una secuencia implícita , mientras que rx-to-stringsolo acepta una única forma, y ​​cualquier secuencia de nivel superior debe hacerse explícita con '(sequence ...)o equivalente.

En resumen, cuando ingresa un formulario '(...)en el re-constructor, se procesa como (rx-to-string '(...))y no(rx ...)

También tenga en cuenta que un formulario no válido puede hacer re-builderque deje de actualizar dinámicamente las coincidencias en el búfer asociado, incluso después de que el formulario vuelva a ser válido. El C-cC-uenlace para reb-force-updatees útil para resolver estas situaciones.


Por defecto, la línea de modo muestra "RE Builder" cuando se usa reado stringsintaxis, y "RE Builder Lisp" cuando se usa rxo sregexsintaxis, pero parece mucho más útil identificar la sintaxis específica en uso (especialmente para diferenciar entre ready string).

Si instala el delightpaquete desde GNU ELPA, puede usar lo siguiente para agregar un indicador de sintaxis a la línea de modo.

(let ((name '("Regexp[" (:eval (symbol-name reb-re-syntax)) "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))

Esto cambia el nombre del modo a "Regexp [lectura]" en readsintaxis, y lo mismo para los demás.

O para incluir una pista para el gotcha rxvs rx-to-stringdescrito anteriormente, haga que la línea de modo diga "Regexp [rx-to-string]" cuando use la rxsintaxis:

(let ((name '("Regexp["
              (:eval (symbol-name (if (eq reb-re-syntax 'rx)
                                      'rx-to-string
                                    reb-re-syntax)))
              "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))
phils
fuente