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

Pregunta:

Quiero usar rx para 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 . Encontré rx-to-string , pero no está claro qué FORMULARIO debería escribir:

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

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

Respuesta:

rx-to-string toma una forma de expresión regular como argumento. La sintaxis es la misma que la del 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-start seguido de una de un montón de cadenas seguido de fin de symbol-end , debe symbol-start con la secuencia del operador de sequence (que puede abreviarse como seq o : o extrañamente par and ).

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

rx es de hecho una pequeña envoltura alrededor de rx-to-string que opera en tiempo de compilación porque es una macro. Lo que hace que esto sea confuso es que si pasa varios argumentos a rx , hay un operador de sequence implícito. La documentación de rx podrí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\\)\\_>"

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım