如何使用rx创建动态正则表达式?


15

我想用来rx创建带有运行时值的正则表达式。

目前,我正在这样做:

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

但是,我宁愿避免使用eval。我已经找到rx-to-string,但尚不清楚我应该写什么形式:

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

如何rx在运行时构建表达式?

Answers:


18

rx-to-string采用正则表达式形式作为参数。语法与的参数相同rx

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

您尝试传递的不是正则表达式表单,而是正则表达式列表。由于您的意思是正则表达式的序列,symbol-start后跟一串字符串中的一个symbol-end,所以您需要使用序列运算符sequence(可以缩写为seqor :,或者甚至很奇怪and)。

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

rx实际上,它是一个很小的包装程序,rx-to-string它在编译时起作用,因为它是一个宏。造成混淆的原因是,如果您向传递多个参数rx,则会有一个隐式sequence运算符。的文档rx可能会有待澄清。

(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
“您将多个参数传递给rx,有一个隐式序列运算符” –啊!那是这里的主要陷阱。谢谢!
Wilfred Hughes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.