2012-03-26 2 views
4

Was ist die korrekte Methode, einen Puffer zu analysieren, um seinen Inhalt zu speichern und wiederzuverwenden?Wie parse ich einen Puffer in elisp richtig?

sagen, dass ich diesen Puffer bekam:

always|five|words|by|line 
not|always|the|same|words 
sometimes|no|lines|at|all 
but|only|five|no|more/less 

Was ist der beste Ansatz wäre, eine Liste von den Symbolen in den Zeilen (und Fehler schön, wenn keine gefunden) gefunden zu konstruieren?

Der Puffer gibt es, ich kann es besuchen, bekommen ihren Inhalt wie so

(message "Buffer content : %s" (buffer-substring (point-min) (point-max))) 

, nachdem ich es sauber getötet, aber irgendwie nicht ich an das Objekt konstruieren (eine Liste „Linien“ von Listen „Worte ") das würde mir erlauben das zu tun:

(list-length lines) 
    ==> 4 

(car (nthcdr 3 lines)) 
    ==> sometimes 

Kann eine verwandte Seele mich auf das Licht richten? Vielen Dank für Ihre Geduld, Lisp Älteste.

+0

Ich glaube, ich habe eine Möglichkeit, die Zeilen zu zählen. Aber was die Speicherung der Wörter in leicht abrufbarer Form betrifft, kein Glück. – yPhil

Antwort

7

Sie könnten auch die Verwendung eingebaute in split-string Funktion, ähnlich wie split in Perl und anderen Sprachen :

(defun buffer-to-list-of-lists (buf) 
    (with-current-buffer buf 
    (save-excursion 
     (goto-char (point-min)) 
     (let ((lines '())) 
     (while (not (eobp)) 
      (push (split-string 
       (buffer-substring (point) (point-at-eol)) "|") 
       lines) 
      (beginning-of-line 2)) 
     (nreverse lines))))) 

Dann mit Ihrem Beispiel Text in einem Puffer temp genannt, (buffer-to-list-of-lists "temp") den Wert

kehrt
(("always" "five" "words" "by" "line") 
("not" "always" "the" "same" "words") 
("sometimes" "no" "lines" "at" "all") 
("but" "only" "five" "no" "more/less")) 

Dies funktioniert auf Zeilen mit einer beliebigen Anzahl von |-getrennte Wörter, die für Ihre Anwendung besser sein können oder nicht. Ändern Sie buffer-substring in buffer-substring-no-properties, wenn die Zeichenfolgen in der Listenliste nicht die Zeichensatzinformationen und andere Eigenschaften enthalten sollen, die sie im ursprünglichen Puffer hatten.

Sobald Sie dies so funktioniert, wie Sie möchten, müssen Sie auch Ihre Beispielverwendung (list-length '(lines)) zu (list-length lines) ändern. In seiner aktuellen Form fragen Sie nach der Länge einer konstanten Ein-Element-Liste, die nur das Symbol lines enthält.

+0

Ich musste eine Sonnenbrille aufsetzen, um Ihre "sur-mesure" Antwort zu lesen. Es ist voller nützlicher Infos, vielen Dank, du bist ein Gentleman und ein Gelehrter :) – yPhil

+0

@PhilippeCM ... und ich musste ein Französisch-Wörterbuch öffnen, um herauszufinden, was "sur-mesure" bedeutet ;-) Froh, es zu tun war hilfreich! –

2

Hier ist eine einfache regexp basierte Parser, der als Start nützlich sein können, zu erreichen, was Sie wollen:

(let (lines) 
    (beginning-of-line) 
    (while (not (eobp)) 
    (push 
    (if (looking-at "\\([^|\n]+\\)|\\([^|\n]+\\)|\\([^|\n]+\\)|\\([^|\n]+\\)|\\([^|\n]+\\)") 
     (list (match-string-no-properties 1) 
       (match-string-no-properties 2) 
       (match-string-no-properties 3) 
       (match-string-no-properties 4) 
       (match-string-no-properties 5))  
     'no-match) 
    lines) 
    (forward-line 1)) 

    (setq lines (nreverse lines)) 

    (print lines)) 
2

Nehmen wir an, dass die Variable text den Inhalt Ihres Puffers als Zeichenfolge enthält, pro Jon O answer. Dann dash.el Liste API und s.el API-Funktionen verwenden:

(--map (s-split "|" it) (s-lines text)) 

--map ist ein anaphoric version von -map, macht es eine temporäre Variable it, so dass Sie müssen nicht eine anonyme Funktion übergeben. s-split ist ein einfacher Wrapper um split-string, s-lines teilt eine Zeichenfolge durch Zeilenumbrüche.

Verwandte Themen