2010-10-18 2 views
9

Возможно, я все об этом ошибаюсь, но я пытаюсь получить все совпадения в строке для определенного шаблона регулярных выражений. Я использую re-matcher, чтобы получить объект матча, который я перехожу на 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

+0

Вы имели в виду «последовательность векторов»? Это то, что было бы возвращено, если у вас есть группа захвата в вашем регулярном выражении. Я добавил еще несколько примеров выше. –

+0

Вы правы: я, должно быть, имел в виду «последовательность векторов». Ваши примеры очистили меня. Благодарю. – exupero