我希望能够在正则表达式上调用curve_fit
,就像这样:
map
如何扩展正则表达式以支持IFn接口?还是有其他方法可以做到?
答案 0 :(得分:2)
(extend-type js/RegExp
IFn
(-invoke
([match s] (re-find match s))
([match replacement s]
(clojure.string/replace s match replacement))))
现在,您可以将正则表达式作为函数来调用,甚至可以将它们传递给map
:
(#"abc+" "abcccc")
=> "abcccc"
(map #"abc+" ["abcccc" "abcccccccc"])
=> ("abcccc" "abcccccccc")
很不幸,IFn
不是Clojure中的协议,因此您不能扩展它。真不幸。
答案 1 :(得分:2)
由于IFn
不是核心Clojure中的协议,所以我认为这是不可能的。
我能得到的最接近的结果是创建一个实现IFn
的包装器类型:
(defrecord R [^java.util.regex.Pattern regex]
clojure.lang.IFn
(invoke [this s]
(re-find regex s))
(invoke [this replacement s]
(clojure.string/replace s regex replacement)))
(map (->R #"abc+") ["abcccc" "abcccccccc"])
=> ("abcccc" "abcccccccc")
答案 2 :(得分:1)
尝试执行此操作的麻烦在于,使用正则表达式无法直接清楚地知道要执行的操作-特别是当大多数生产代码看起来像(map #"ab+" entries)
时
正则表达式仅与模式 matching 有关,它们并不直接暗示您要从它们中进行什么转换,因此,您真的应该避免尝试将其转换为错误模式。
如果是一次,请使用
(map #(clojure.string/replace % #"ab+c*" "ab") ["ab" "ac" "abbcc"])
=> ("ab" "ac" "ab")
(尚不清楚您的示例应如何工作?结果中包含的元素更少-您正在过滤和转换吗?如何获得“ abbb”元素?)< / p>
如果您经常使用它,我建议您仅在可与map
一起使用的通用命名空间中创建一个辅助函数,而不要尝试扩展IFn接口。。由于创建函数
答案 3 :(得分:0)
正如CmdrDats所说,在匿名函数中使用re-find
绝对是可行的方法:
(filter #(re-find #"ab+c*" %) ["abbb" "ac" "abbcc"])
=> ("abbb" "abbcc")
有时我会使用一个辅助函数来强调我只想要正确/错误的输出(而不是匹配项或一系列匹配项),并且由于我总是忘记re-xxx
函数之间的区别:>
(ns demo.core
(:require [schema.core :as s]))
(s/defn contains-match? :- s/Bool
"Returns true if the regex matches any portion of the intput string."
[search-str :- s/Str
re :- s/Any]
#?(:clj (assert (instance? java.util.regex.Pattern re)))
(boolean (re-find re search-str)))