¿Cómo creo una expresión regular dinámica con rx?


15

Quiero usar rxpara crear expresiones regulares con valores de tiempo de ejecución.

Actualmente, estoy haciendo esto:

(setq strings '("foo" "bar" "baz"))
(eval `(rx symbol-start (or ,@strings) symbol-end))

Sin embargo, prefiero evitar usar eval. He encontrado rx-to-string, pero no está claro qué FORM debería escribir:

;; error: Unknown rx form `symbol-start
(rx-to-string '(symbol-start (or ,@strings) symbol-end))

¿Cómo construyo una rxexpresión en tiempo de ejecución?

Respuestas:


18

rx-to-stringtoma una forma regexp como argumento. La sintaxis es la misma que el argumento de rx.

(rx-to-string '(or "foo" "bar"))
"\\(?:\\(?:bar\\|foo\\)\\)"

Lo que intentó pasar no es un formulario regexp, sino una lista de formularios regexp. Dado que lo que quiere decir es la secuencia de expresiones regulares symbol-startseguidos por uno de un puñado de cadenas seguido de symbol-end, es necesario conducir con el operador de secuencia sequence(que se puede abreviar como seqo :, o incluso extrañamente and).

(rx-to-string `(: symbol-start (or ,@strings) symbol-end))
"\\(?:\\_<\\(?:ba[rz]\\|foo\\)\\_>\\)"

rxDe hecho, es un pequeño contenedor rx-to-stringque funciona en tiempo de compilación porque es una macro. Lo que hace que esto sea confuso es que si le pasas múltiples argumentos rx, hay un sequenceoperador implícito . La documentación de rxpodría ser aclarada.

(rx (: symbol-start (or "foo" "bar" "baz") symbol-end))
"\\_<\\(?:ba[rz]\\|foo\\)\\_>"
(rx symbol-start (or "foo" "bar" "baz") symbol-end)
"\\_<\\(?:ba[rz]\\|foo\\)\\_>"

77
"se pasan múltiples argumentos a rx, hay un operador de secuencia implícito" - ¡aja! Ese es el principal problema aquí. ¡Gracias!
Wilfred Hughes
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.