Comment créer une expression rationnelle dynamique avec rx?


15

Je souhaite utiliser rxpour créer des expressions régulières avec des valeurs d'exécution.

Actuellement, je fais ceci:

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

Cependant, je préfère éviter d'utiliser eval. J'ai trouvé rx-to-string, mais la forme que je dois écrire n'est pas claire:

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

Comment créer une rxexpression au moment de l'exécution?

Réponses:


18

rx-to-stringprend une forme d'expression régulière comme argument. La syntaxe est la même que l'argument de rx.

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

Ce que vous avez essayé de transmettre n'est pas un formulaire d'expression régulière, mais une liste de formulaires d'expression régulière. Étant donné que vous voulez dire la séquence d'expressions régulières symbol-startsuivie d'une chaîne de chaînes suivie symbol-end, vous devez diriger avec l'opérateur de séquence sequence(qui peut être abrégé en seqou :, ou bizarrement même and).

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

rxest en fait un petit wrapper rx-to-stringqui fonctionne au moment de la compilation car c'est une macro. Ce qui rend cela déroutant, c'est que si vous passez plusieurs arguments à rx, il existe un sequenceopérateur implicite . La documentation de rxpourrait être clarifiée.

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

8
"vous passez plusieurs arguments à rx, il y a un opérateur de séquence implicite" - aha! C'est le principal problème ici. Merci!
Wilfred Hughes
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.