Làm cách nào để tạo regrec động với rx?


15

Tôi muốn sử dụng rxđể tạo các biểu thức thông thường với các giá trị thời gian chạy.

Hiện tại, tôi đang làm điều này:

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

Tuy nhiên, tôi muốn tránh sử dụng eval. Tôi đã tìm thấy rx-to-string, nhưng không rõ MẪU tôi nên viết gì:

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

Làm thế nào để tôi xây dựng một rxbiểu thức trong thời gian chạy?

Câu trả lời:


18

rx-to-stringlấy một hình thức regex làm đối số. Cú pháp giống như đối số của rx.

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

Những gì bạn đã cố gắng vượt qua không phải là một hình thức regex, mà là một danh sách các hình thức regex. Vì ý của bạn là chuỗi các biểu thức chính quy được symbol-starttheo sau bởi một chuỗi các chuỗi theo sau symbol-end, nên bạn cần phải dẫn đầu với toán tử trình tự sequence(có thể được viết tắt thành seqhoặc :, hoặc thậm chí kỳ lạ and).

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

rxthực tế là một trình bao bọc nhỏ xung quanh rx-to-stringhoạt động vào thời gian biên dịch vì nó là một macro. Điều làm cho điều này trở nên khó hiểu là nếu bạn truyền nhiều đối số cho rx, có một sequencetoán tử ẩn . Các tài liệu của rxcó thể đứng để được làm rõ.

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

7
"bạn chuyển nhiều đối số cho rx, có một toán tử trình tự ẩn" - aha! Đó là gotcha chính ở đây. Cảm ơn!
Wilfred Hughes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.