Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 用于正则表达式匹配及其在字符串中的位置的压缩Clojure代码_Regex_Clojure - Fatal编程技术网

Regex 用于正则表达式匹配及其在字符串中的位置的压缩Clojure代码

Regex 用于正则表达式匹配及其在字符串中的位置的压缩Clojure代码,regex,clojure,Regex,Clojure,Stuart Halloway给出了一个例子 (re-seq #"\w+" "The quick brown fox") 作为在Clojure中查找正则表达式匹配项的自然方法。在他的书中,这种结构与匹配器上的迭代形成对比。如果所有人关心的都是一份比赛名单,那就太好了。但是,如果我想要匹配项及其在字符串中的位置,该怎么办?有没有更好的方法可以让我利用java.util.regex中的现有功能,对原始字符串中的每个索引进行序列理解?换言之,您可能会键入以下内容 (关于“地图”#“[0-9]+”3a

Stuart Halloway给出了一个例子

(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"}