2011-07-26 63 views
1

我使用Clojure來解析和分析XML文件。
下面是一個示例:如何提取last:last之前的最後一個值,但在最後一個逗號之後?

BSS:17,NSVC:1 
BSS:17,NSVC:4 
BSS:17,NSVC:5 
BSS:17,BTSM:0,BTS:3 
BSS:17,BTSM:0,BTS:4 
BSS:17,BTSM:0,BTS:5 
BSS:17,BTSM:1,BTS:0 
BSS:17,BTSM:1,BTS:1 
BSS:17,BTSM:1,BTS:2 
BSS:17,BTSM:1,BTS:3 

我感興趣的是最後的值(最後一個逗號之後,但值前的最後:,NSVS在我的情況下,BTS),之後他們的數字並不重要。
如何提取上一個字符串中的最後一個值?

+1

如果你的名字/值總是[AZ]和[0-9],這是一個非常簡單的正則表達式:'(AZ)+:[0-9] + $' –

+0

@Alex(再以次#「(AZ)+:[0-9] + $」「BSS:17,BTSM:14,BTS:4」)返回無 – Chiron

回答

3

您可以使用此函數來處理各條線:

(defn lastval [s] 
    (second (re-find #",([^,:]+):\d*$" s))) 
       ; ^the comma preceding the interesting section 
       ; ^the part in parens will be captured as a group 
       ; ^character class meaning "anything except , or :" 
       ;   ^the colon after the interesting section 
       ;   ^any number of digits after the colon 
       ;    ^end of string 
      ;^returns a vector of [part-that-matches, first-group]; 
      ; we're interested in the latter, hence second 

NB。如果正則表達式不匹配,則返回nil

例如爲:

user> (lastval "BSS:17,BTSM:0,BTS:3") 
"BTS" 

如果以後想要提取的所有信息便於工作有位,你可以使用

(defn parse [s] 
    (map (juxt second #(nth % 2)) (re-seq #"(?:^|,)([^,:]+):(\d+)" s))) 

例如

user> (parse "BSS:17,BTS:0,BTS:3") 
(["BSS" "17"] ["BTS" "0"] ["BTS" "3"]) 
+0

如果我要與Clojure開發人員一起工作,我希望我可以與您合作。世界級的代碼。我第一次閱讀有關juxt功能。謝謝。 – Chiron

+0

你用過重新發現,爲什麼你沒有使用re-seq? – Chiron

+0

樂意幫忙!我想你會發現這種代碼在Clojure中很常見。 :-)至於你的問題:'re-find'只返回一個匹配項(如果有的話)(如果你傳遞一個正則表達式和一個字符串,第一個;如果你傳入一個Matcher對象,那麼下一個;例如try'(let [m(re-matcher#「(foo | bar)」「foobar」)] [(re-find m)(re-find m)])')。 're-seq'返回所有匹配的一個seq。由於在'lastval'函數中我們只需要一次匹配,'re-find'是該工作的正確工具。請注意,上面的'parse'確實使用're-seq',因爲它確實需要允許多個匹配。 –

0

這是否適合您?

 

(def tmp (str "BSS:17,NSVC:1\n 
BSS:17,NSVC:4\n 
BSS:17,NSVC:5\n 
BSS:17,BTSM:0,BTS:3\n 
BSS:17,BTSM:0,BTS:4\n 
BSS:17,BTSM:0,BTS:5\n 
BSS:17,BTSM:1,BTS:0\n 
BSS:17,BTSM:1,BTS:1\n 
BSS:17,BTSM:1,BTS:2\n 
BSS:17,BTSM:1,BTS:3\n")) 


(defn split [s sep] 
    (->> (.split s sep) 
     seq 
     (filter #(not (empty? %))))) 

(reduce (fn[h v] 
      (conj h (last v))) 

      [] (map #(split % ",") 
        (split tmp "\n"))) 
 

我假設行之間有某種分隔符。

相關問題