ฉันจะสร้าง regexp แบบไดนามิกด้วย 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แสดงออกที่รันไทม์ได้อย่างไร

คำตอบ:


18

rx-to-stringใช้แบบฟอร์ม regexp เป็นอาร์กิวเมนต์ rxไวยากรณ์เป็นเช่นเดียวกับข้อโต้แย้งของ

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

สิ่งที่คุณพยายามผ่านไม่ใช่แบบฟอร์ม regexp แต่รายการแบบฟอร์ม regexp เนื่องจากสิ่งที่คุณหมายถึงคือลำดับของนิพจน์ทั่วไปที่symbol-startตามมาด้วยหนึ่งในสตริงที่ตามมาsymbol-endคุณจึงต้องนำด้วยตัวดำเนินการลำดับsequence(ซึ่งสามารถย่อseqหรือ:หรือแปลก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 มีโอเปอเรเตอร์ลำดับโดยนัย" - aha! นั่นคือ gotcha หลักที่นี่ ขอบคุณ!
Wilfred Hughes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.