1

我正在尝试创建一个接受 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))

谢谢!

4

2 回答 2

4

你很近;但是您不需要(并且可能不应该使用)宏:

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

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

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

(defmacro checkre [ strre strstring ] 
  `(re-find ~(re-pattern strre) ~strstring))
(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))
(hasthing "stuff blabla")
;=> "stuff blabla"
于 2013-01-28T19:58:13.227 回答
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"
于 2013-01-28T19:58:02.863 回答