2012-05-10 5 views
1

내가보기에 텍스트 파일이있는 경우 데이터 덩어리로 탭 구분 된 문자열을 분리하는 방법을 알아 내는데 어려움이 있습니다.파스 탭으로 구분 된 문자열

a1  b1  c1  d1  e1 
a2  b2  c2  d2  e2 

그리고 난 내 파일의 첫 번째 줄을 읽고 ABCDE (

"a1  b1  c1  d1  e2" 

의 내가 5 개 변수에 A, B, C, D 및 E를이 분리, 또는 목록을 만들려면 문자열을 얻을). 이견있는 사람?

감사합니다.

+0

지금까지 기록 된 것을 우리에게 보여주십시오 . –

+0

아직 아무것도 쓰지 않았어요. 원래 코드가 Perl로 작성되어있어서 그것을 리습으로 변환해야합니다. 실제로 그것을 수행하는 가장 좋은 방법은 무엇인지 모르겠습니다. 나는 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'는 '벡터'여야합니다. '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") 
관련 문제