Як створити динамічне регулярне вираження за допомогою 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приймає форму аргументації. Синтаксис такий самий, як і аргумент rx.

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

Те, що ви спробували пройти, - це не форма 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, є оператор неявної послідовності" - ага! Ось тут головна готча. Спасибі!
Вільфред Х'юз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.