2012-05-10 17 views
1

タブの区切り文字列を例としてデータの区切りにする方法がわかりません。このようなテキストファイルがある場合は解析タブ区切り文字列

a1  b1  c1  d1  e1 
a2  b2  c2  d2  e2 

と私は私のファイルの最初の行を読んで、私は5つの変数、b、c、d、およびeにこれを分離、またはリストを作成したい

"a1  b1  c1  d1  e2" 

の文字列(ABCDEを得ます)。何かご意見は?

ありがとうございました。

+0

あなたがこれまでに書かれたものを私たちに示してください。 。 –

+0

私はまだ何も書いていません。私の元のコードはPerlで書かれており、私はそれをlispに変換する必要があります。私はプログラムに組み込むだけでtxtファイルを読み込むのではなく、必要に応じて変更する方が簡単かもしれないと思っています。 – Lpaulson

答えて

2

括弧を入力文字列の前後に連結し、次にread-from-stringを使用してみてください(私はあなたの質問clispにタグを付けたので、Common Lispを使用していると仮定します)。

(setf str "a1 b1  c1  d1  e2") 
(print (read-from-string (concatenate 'string "(" str ")"))) 
2

(少しより堅牢な、多分)あなたは `setfの」コールバックに一度、文字列内の文字が呼び出されることができるように、あなたはまた、簡単に、それを変更することができますが、私はdidnのそれについて移動するさらに別の方法あなたがこのような能力を必要としていないように思えるので、そうしないでください。また、後のケースでは、むしろマクロを使用したいと思います。あなたは、あなたがそれを読んで文字列を変更したい場合はここで

(defun mapc-words (function vector 
        &aux (whites '(#\Space #\Tab #\Newline #\Rubout))) 
    "Iterates over string `vector' and calls the `function' 
with the non-white characters collected so far. 
The white characters are, by default: #\Space, #\Tab 
#\Newline and #\Rubout. 
`mapc-words' will short-circuit when `function' returns false." 
    (do ((i 0 (1+ i)) 
     (start 0) 
     (len 0)) 
     ((= i (1+ (length vector)))) 
    (if (or (= i (length vector)) (find (aref vector i) whites)) 
     (if (> len 0) 
      (if (not (funcall function (subseq vector start i))) 
       (return-from map-words) 
       (setf len 0 start (1+ i))) 
      (incf start)) 
     (incf len))) vector) 

(mapc-words 
#'(lambda (word) 
    (not 
     (format t "word collected: ~s~&" word))) 
"a1  b1  c1  d1  e1 
a2  b2  c2  d2  e2") 

;; word collected: "a1" 
;; word collected: "b1" 
;; word collected: "c1" 
;; word collected: "d1" 
;; word collected: "e1" 
;; word collected: "a2" 
;; word collected: "b2" 
;; word collected: "c2" 
;; word collected: "d2" 
;; word collected: "e2" 

は、あなたが使用できるマクロの例ですが、私はそれに完全に満足していない、ので、多分誰かがよりよいバリアントを考え出すだろう。

(defmacro with-words-in-string 
    ((word start end 
      &aux (whites '(#\Space #\Tab #\Newline #\Rubout))) 
    s 
    &body body) 
    `(do ((,end 0 (1+ ,end)) 
     (,start 0) 
     (,word) 
     (len 0)) 
     ((= ,end (1+ (length ,s)))) 
    (if (or (= ,end (length ,s)) (find (aref ,s ,end) ',whites)) 
     (if (> len 0) 
      (progn 
       (setf ,word (subseq ,s ,start ,end)) 
       ,@body 
       (setf len 0 ,start (1+ ,end))) 
      (incf ,start)) 
     (incf len)))) 

(with-words-in-string (word start end) 
    "a1  b1  c1  d1  e1 
a2  b2  c2  d2  e2" 
(format t "word: ~s, start: ~s, end: ~s~&" word start end)) 
+0

私はMAP-WORDSのデザインの面に本当に満足していません。私は出口機能に入れないだろう。 CLライブラリはそれを使用せず、マッピングの終了は、提供された関数自体(CLメカニズムのいずれかを使用して、戻り値、スロー値、条件シグナリングなど)によって行うことができます。 CLは名前 'コールバック'も使用しません。これは、少し異なる(イベント駆動型またはアクセス指向型)ことを意味します。 CL標準では、「関数」が使用されます。 'x'は 'vector'でなければなりません。 'map-words'は 'mapc-words'で、そのベクトルを返します。 –

+0

(remove-if# 'consp some-list:count 10)、REMOVE-IFにはKEYパラメータもあります。 –

0

、これは以下になり、リスト

(defun tokenize-tabbed-line (line) 
    (loop 
    for start = 0 then (+ space 1) 
    for space = (position #\Tab line :start start) 
    for token = (subseq line start space) 
    collect token until (not space))) 

を作成します。彼らは(間隔ません)タブ付きされていると仮定:

CL-USER> (tokenize-tabbed-line "a1 b1 c1 d1 e1") 
("a1" "b1" "c1" "d1" "e1") 
関連する問題