2010-08-06 14 views
10

Estoy creando una macro de conveniencia. Parte de la conveniencia es que una expresión regular se puede especificar con solo una cadena, en lugar de la notación # "re".¿Cómo escribo una macro de Clojure para crear una expresión regular a partir de una cadena?

La única parte que no puedo entender es cómo hacer que la macro tome la cadena y volver a escribirla como una expresión regular Clojure (por ejemplo, producir la notación # "re"). Creo que es un problema de sintaxis/escape.

Mi primer intento ingenuo (pretendiendo sólo quiero la parte de cadena a expresiones regulares):

(defmacro mymac [mystr] `#~mystr) 

¿Es incluso posible hacer lo que estoy tratando de hacer? O, ¿hay una función real para tomar una cadena y producir una expresión regular, en lugar de utilizar la macro # lector?

¿O debería simplemente caer en Java y usar java.util.regex.Pattern?

Respuesta

28

hay una función para ello: re-pattern

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

Es posible que esté malinterpretando la pregunta, pero ¿no hace esto lo que quiere?

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

sí, hace exactamente lo que quiero. pero tienes que admitir que no es tan bonito como j-g-faustus (re-pattern "mystr") – dirtyvagabond

+0

No, de hecho no. – Sean

7

Para explicar un poco más:

#"" es una macro lector. Se resuelve en el momento de la lectura por el lector. De modo que no hay forma de crear una macro que se expanda en una macro de lector, porque la fase de lectura ha desaparecido. Una macro devuelve la estructura de datos real que representa el código expandido, no una cadena que se analiza de nuevo como, por ejemplo. #define funciona en C.

La respuesta de j-g-faustus es la correcta (tm) para ir.

+0

Gracias kotarak. Debería haberme dado cuenta de por qué el ciclo de vida del lector me impide hacer lo que estaba tratando de hacer. ¡Gracias! – dirtyvagabond

0

para que coincida con una cadena pie de la letra, haciendo caso omiso de caracteres especiales:

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

Entonces ... sólo igualará ..., no aaa o cualquier otra combinación de tres letras.

Cuestiones relacionadas