我正在尝试创建一个接受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))
谢谢!
答案 0 :(得分: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"
答案 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"