2011-07-26 8 views
1

私はXMLファイルを解析して分析するためにClojureを使用しています。ここで
はサンプルです:最後の値を最後に抽出する方法:文字ですか、最後のカンマの後に?

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")はnilを返す – 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-findを使用しました、なぜre-seqを使用しなかったのですか? – Chiron

+0

お手伝いします!私は、この種のコードがClojureではかなり一般的であることがわかります。 :-)あなたの質問について: 're-find'はもしあれば正規表現と文字列を渡すと最初のものを返します; Matcherオブジェクトを渡すと"次のもの "例えば、 ''(re-matcher# "(foo | bar)" "foobar")] [(re-find m)(re-find m)]) ')を試してみてください。 're-seq'はすべての一致のseqを返します。 'lastval'関数では単一のマッチだけが期待されるので、' re-find'はジョブの正しいツールです。上記の 'parse'は実際に' re-seq'を使用します。なぜなら、複数のマッチを許す必要があるからです。 –

0

最後にコンマを見つけるにはlastIndexOfを使用できますか?

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"))) 
 

私は線の間にある種の区切りがあると仮定しています。

関連する問題