Regex 用于正则表达式匹配及其在字符串中的位置的压缩Clojure代码
Stuart Halloway给出了一个例子Regex 用于正则表达式匹配及其在字符串中的位置的压缩Clojure代码,regex,clojure,Regex,Clojure,Stuart Halloway给出了一个例子 (re-seq #"\w+" "The quick brown fox") 作为在Clojure中查找正则表达式匹配项的自然方法。在他的书中,这种结构与匹配器上的迭代形成对比。如果所有人关心的都是一份比赛名单,那就太好了。但是,如果我想要匹配项及其在字符串中的位置,该怎么办?有没有更好的方法可以让我利用java.util.regex中的现有功能,对原始字符串中的每个索引进行序列理解?换言之,您可能会键入以下内容 (关于“地图”#“[0-9]+”3a
(re-seq #"\w+" "The quick brown fox")
作为在Clojure中查找正则表达式匹配项的自然方法。在他的书中,这种结构与匹配器上的迭代形成对比。如果所有人关心的都是一份比赛名单,那就太好了。但是,如果我想要匹配项及其在字符串中的位置,该怎么办?有没有更好的方法可以让我利用java.util.regex中的现有功能,对原始字符串中的每个索引进行序列理解?换言之,您可能会键入以下内容
(关于“地图”#“[0-9]+”3a1b2c1d)
它将返回一个地图,其中键作为位置,值作为匹配项,例如
{0 "3", 2 "1", 4 "2", 6 "1"}
在现存的库中是否已经实现了这一点,或者我应该编写它(不应该太多代码行) 您可以从
java.util.regex.Matcher
对象中获取所需的数据
user> (defn re-pos [re s]
(loop [m (re-matcher re s)
res {}]
(if (.find m)
(recur m (assoc res (.start m) (.group m)))
res)))
#'user/re-pos
user> (re-pos #"\w+" "The quick brown fox")
{16 "fox", 10 "brown", 4 "quick", 0 "The"}
user> (re-pos #"[0-9]+" "3a1b2c1d")
{6 "1", 4 "2", 2 "1", 0 "3"}
您可以对java.util.regex.Matcher对象应用任何函数并返回其结果(类似于Brian的解决方案,但没有显式的
循环
):
谢谢你,布莱恩。也许re-pos应该进入正则表达式库。我对此有点问题。(re pos#“ATAT”gatatatgcatatact)应该返回{9“ATAT”,3“ATAT”,1“ATAT},但它返回{9”ATAT,1“ATAT}。如果要计算重叠的匹配,请稍微更改正则表达式:(re pos#“(?=(ATAT))“gatatatgcatatact”)返回{9”,“3”,“1”“)。如果你想找回匹配的文本,你需要做的是(.groupm1)而不是(.groupm)。有人能解释一下#“(?=(ATAT))”是什么意思吗?这是什么意思?
user=> (defn re-fun
[re s fun]
(let [matcher (re-matcher re s)]
(take-while some? (repeatedly #(if (.find matcher) (fun matcher) nil)))))
#'user/re-fun
user=> (defn fun1 [m] (vector (.start m) (.end m)))
#'user/fun1
user=> (re-fun #"[0-9]+" "3a1b2c1d" fun1)
([0 1] [2 3] [4 5] [6 7])
user=> (defn re-seq-map
[re s]
(into {} (re-fun re s #(vector (.start %) (.group %)))))
user=> (re-seq-map #"[0-9]+" "3a1b2c1d")
{0 "3", 2 "1", 4 "2", 6 "1"}