2010-10-18 56 views
9

也许我正在讨论这一切都是错误的,但我试图让一个特定的正则表达式模式的字符串中的所有匹配。我使用re-matcher来获取Match对象,我将其传递给re-find,给我(full-string-match,grouped-text)对。我如何获得Match对象产生的所有匹配序列?Clojure:获取正则表达式匹配列表

在Clojuresque Python中,它看起来像:

pairs = [] 
match = re-matcher(regex, line) 

while True: 
    pair = re-find(match) 
    if not pair: break 
    pairs.append(pair) 

有什么建议?

回答

21

您可能想要使用内置的re-seq和Clojure内置的正则表达式。除非你真的拥有这些Java对象,否则不要嘲笑它。

(doc re-seq) 


clojure.core/re-seq 
([re s]) 
    Returns a lazy sequence of successive matches of pattern in string, 
    using java.util.regex.Matcher.find(), each such match processed with 
    re-groups. 

For example:

user> (re-seq #"the \w+" "the cat sat on the mat") 
("the cat" "the mat") 

In answer to the follow-up comment, group captures will result in a vector of strings with an element for each part of the group in a match:

user> (re-seq #"the (\w+(t))" "the cat sat on the mat") 
(["the cat" "cat" "t"] ["the mat" "mat" "t"]) 

You can extract a specific element by taking advantage of the elegant fact that vectors are functions of their indices.

user> (defn extract-group [n] (fn [group] (group n))) 
#'user/extract-group 
user> (let [matches (re-seq #"the (\w+(t))" "the cat sat on the mat")] 
     (map (extract-group 1) matches)) 
("cat" "mat") 

Or you can destructure the matches (here using a for宏去了所有的比赛,但是这也可以在let或函数参数绑定)来完成:

user> (dorun 
     (for [[m1 m2 m3] (re-seq #"the (\w+(t))" "the cat sat on the mat")] 
      (do (println "m1:" m1) 
       (println "m2:" m2) 
       (println "m3:" m3)))) 
m1: the cat 
m2: cat 
m3: t 
m1: the mat 
m2: mat 
m3: t 
+0

这就是我要找的,但我发现一个不同的结果:一个列表矢量,而不是一个字符串矢量。 – exupero 2010-10-19 12:28:25

+0

你是不是指“矢量序列”?如果您在正则表达式中捕获组,将会返回这个结果。我在上面添加了更多示例。 – 2010-10-19 14:42:14

+0

你说得对:我一定是指'矢量序列'。你的例子已经为我清理了一些东西。谢谢。 – exupero 2010-10-20 12:35:37