2010-08-06 13 views
10

Sto creando una macro di comodità. Parte della praticità è che un'espressione regolare può essere specificata solo con una stringa, piuttosto che con la notazione # "re".Come scrivere una macro Clojure per creare un'espressione regolare da una stringa?

L'unica parte che non riesco a capire è come ottenere la macro di prendere la corda e riscriverlo come una regex Clojure (ad esempio, produrre il # "ri" notazione). Penso che sia un problema di sintassi/fuga.

Il mio primo tentativo ingenuo (fingendo io voglio solo la parte String-a-regex):

(defmacro mymac [mystr] `#~mystr) 

E 'anche possibile fare quello che sto cercando di fare? Oppure, esiste una funzione effettiva per prendere una stringa e produrre un'espressione regolare, invece di utilizzare la macro # reader?

O dovrei semplicemente entrare in Java e usare java.util.regex.Pattern?

risposta

28

c'è una funzione per esso: re-pattern

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

Posso essere fraintendere la domanda, ma questo non fa quello che vuoi?

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

sì, fa esattamente quello che voglio. ma devi ammettere, non bello come quello di j-g-faustus (re-pattern "mystr") – dirtyvagabond

+0

No, anzi no. – Sean

7

per spiegare un po 'di più:

#"" è una macro lettore. È risolto al momento della lettura dal lettore. Quindi non c'è modo di creare una macro che si espande in una macro di lettore, perché la fase di lettura è finita da tempo. Una macro restituisce la struttura dati effettiva che rappresenta il codice espanso, non una stringa che viene nuovamente analizzata come ad es. #define funziona in C.

j-g-faustus 'la risposta è il modo giusto (tm) per andare.

+0

Grazie kotarak. Avrei dovuto capire perché il ciclo di vita del lettore mi impedisce di fare ciò che stavo cercando di fare. Grazie! – dirtyvagabond

0

per abbinare una stringa verbatim, ignorando i caratteri speciali:

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

Poi ... selezionerà solo ..., non aaa o qualsiasi altra combinazione di tre lettere.

Problemi correlati