Как написать макрос Clojure для создания регулярного выражения из строки? - PullRequest
11 голосов
/ 06 августа 2010

Я создаю удобный макрос. Отчасти удобство заключается в том, что регулярное выражение можно указывать только с помощью String, а не с помощью обозначения «re».

Одна часть, которую я не могу понять, это как заставить макрос взять строку и переписать ее как регулярное выражение Clojure (например, создать нотацию «re»). Я думаю, что это проблема синтаксиса / экранирования.

Моя первая наивная попытка (притворяясь, что я хочу только часть String-to-regex):

(defmacro mymac [mystr] `#~mystr)

Возможно ли вообще сделать то, что я пытаюсь сделать? Или есть ли реальная функция для взятия строки и создания регулярного выражения вместо использования макроса # reader?

Или я должен просто зайти в Java и использовать java.util.regex.Pattern?

Ответы [ 4 ]

29 голосов
/ 06 августа 2010

Для этого есть функция: re-pattern

user=> (re-pattern "\\d+")
#"\d+"
7 голосов
/ 06 августа 2010

Чтобы объяснить немного больше:

#"" - это макрос считывателя.Это решается во время чтения читателем.Таким образом, нет способа создать макрос, который расширяется в макрос читателя, потому что фаза чтения давно прошла.Макрос возвращает фактическую структуру данных, представляющую расширенный код, а не строку, которая анализируется снова, например.#define работает в C.

jg-faustus ответ - правильный путь (tm).

0 голосов
/ 09 июля 2015

Для совпадения дословно строки без учета специальных символов:

(defn to-regex [some-string]
  (re-pattern (java.util.regex.Pattern/quote some-string)))

Тогда ... будет соответствовать только ..., а не aaa или любой другой трехбуквенной комбинации.

0 голосов
/ 06 августа 2010

Возможно, я неправильно понимаю вопрос, но разве это не то, что вы хотите?

user=> (. java.util.regex.Pattern compile "mystr")
#"mystr"
...