Clojure Regex Macro

时间:2013-01-28 19:32:56

标签: clojure

我正在尝试创建一个接受2个字符串的宏,1个是正则表达式模式,另一个是测试它的字符串。从一些阅读(包括在这里)和看到#“”是一个读者宏我尝试使用re-pattern,但它似乎在运行时失败:

  

线程“main”中的异常java.lang.ClassCastException:clojure.lang.Symbol无法强制转换为java.lang.CharSequence

我的代码:

(defmacro checkre [ strre strstring ] 
  (re-find (re-pattern strre) strstring))

示例电话:

(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))

谢谢!

2 个答案:

答案 0 :(得分:4)

你很亲密;但你不需要(也可能不应该使用)宏:

(defn checkre [ strre strstring ] 
  (re-find (re-pattern strre) strstring))
(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))
(hasthing "stuff blabla")
;=> "stuff blabla"

宏最好只在需要时使用,因为它们不像函数那样容易编写并且更难以推理(因为宏扩展阶段)。

您的宏版本失败的原因是它在宏扩展时尝试绑定strrestrstring,当它们是符号而不是字符串时。一个(稍微变态)的宏版本有效:

(defmacro checkre [ strre strstring ] 
  `(re-find ~(re-pattern strre) ~strstring))
(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))
(hasthing "stuff blabla")
;=> "stuff blabla"

答案 1 :(得分:1)

为什么要把它变成一个宏?只需使它成为一个功能,它就可以正常工作。

=> (defn checkre 
     [strre strstring] 
     (re-find (re-pattern strre) strstring))
#'user/checkre
=> (checkre "[aeiou]" "Hello")
"e"

如果要创建绑定正则表达式的函数,请让函数返回函数

=> (defn checkre 
     [strre] 
     (fn [strstring] (re-find (re-pattern strre) strstring)))
=> (def hasthing (checkre "[aeiou]"))
=> (hasthing "Hello")
"e"