2010-10-18 14 views
9

Forse sto sbagliando tutto questo, ma sto cercando di ottenere tutte le corrispondenze in una stringa per un particolare modello regolare. Sto usando re-matcher per ottenere un oggetto Match, che passo a re-find, dandomi coppie (full-string-match, grouped-text). Come otterrei una sequenza di tutte le partite prodotte dall'oggetto Match?Clojure: ottieni un elenco di corrispondenze di espressioni regolari

In Clojuresque Python, sarebbe simile:

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

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

Qualche suggerimento?

risposta

21

Probabilmente si desidera utilizzare il valore predefinito re-seq e letterale incorporato di Clojure. Non scherzare con gli oggetti java sottostanti a meno che tu non lo abbia davvero.

(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 macro di andare in tutte le partite, ma questo potrebbe anche essere fatto in un argomento let o una funzione vincolante):

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

Questo è quello che sto cercando, ma mi sto un risultato diverso: un vettore di liste, non un vettore di stringhe. – exupero

+0

Intendevi una "sequenza di vettori"? Questo è ciò che verrebbe restituito se si registra un gruppo nella regex. Ho aggiunto alcuni altri esempi sopra. –

+0

Hai ragione: dovevo aver inteso "sequenza di vettori". I tuoi esempi hanno chiarito le cose per me. Grazie. – exupero

Problemi correlati