2010-08-06 150 views
10

我正在創建一個方便的宏。部分方便之處在於,可以使用String來指定正則表達式,而不是#「re」表示法。如何編寫Clojure宏以從字符串創建正則表達式?

我無法弄清楚的一個部分是如何讓宏接受字符串並將其重寫爲Clojure正則表達式(例如,生成#「re」符號)。我認爲這是一個語法/轉義問題。

我第一次嘗試天真(假裝我只希望字符串到正則表達式的部分):

(defmacro mymac [mystr] `#~mystr) 

它甚至有可能做我想要做什麼?或者,是否有一個實際的函數來獲取一個字符串並生成一個正則表達式,而不是使用#reader宏?

或者我應該放入Java並使用java.util.regex.Pattern?

回答

28

有一個功能是:re-pattern

user=> (re-pattern "\\d+") 
#"\d+" 
0

我可能會誤解這個問題,但是這不是你想要的嗎?

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

是的,它確實是我想要的。但你不得不承認,不如j-g-faustus(重新模式「mystr」)那樣漂亮。 – dirtyvagabond 2010-08-06 15:29:10

+0

不,事實上並非如此。 – Sean 2010-08-06 16:14:14

7

要解釋一點:

#""是讀者宏。它在讀者閱讀時解決。所以沒有辦法創建一個擴展到讀者宏的宏,因爲讀階段已經過去了。宏返回代表擴展代碼的實際數據結構,而不是像例如一樣再次解析的字符串。 #定義在C中工作。

j-g-faustus'的答案是正確的方法(tm)。

+0

謝謝kotarak。我應該已經意識到爲什麼讀者的生命週期阻止我做我想做的事情。謝謝! – dirtyvagabond 2010-08-06 15:30:12

0

要逐字匹配的字符串,忽略特殊字符:

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

然後...將只匹配...,不aaa或任何其他三個字母的組合。