如何正确解析elisp中的缓冲区?

时间:2012-03-26 12:21:41

标签: emacs elisp

解析缓冲区以存储其内容并重用它的正确方法是什么?

说我有这个缓冲区:

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

从行中找到的符号构造列表的最佳方法是什么(如果没有找到,则错误很好)?

缓冲区在那里,我可以访问它,得到它的内容

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

我干净地杀了它,但不知怎的,我在构造对象(列表“行”的列表“行”)上失败了,这将允许我这样做:

(list-length lines)
    ==> 4

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

一个有同情心的灵魂可以指向光明吗?谢谢你的耐心,Lisp长老。

3 个答案:

答案 0 :(得分:7)

您还可以使用内置的split-string函数,类似于Perl和其他语言中的split

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

然后将您的示例文本放在名为temp的缓冲区中,(buffer-to-list-of-lists "temp")返回值

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

这适用于包含任意数量的|个单词的行,这些单词可能会或可能不会更适合您的应用。如果您不希望列表列表中的字符串包含它们在原始缓冲区中的字体信息和其他属性,请将buffer-substring更改为buffer-substring-no-properties

按照您的意愿开始运行后,您还需要将示例用量(list-length '(lines))更改为(list-length lines)。在当前形式中,您要求的是一个仅包含符号lines的常量单元素列表的长度。

答案 1 :(得分:3)

我们假设变量text包含缓冲区内容为字符串,每Jon O answer。然后使用dash.el列表API和s.el API函数:

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

--map-map的{​​{3}},它会公开一个临时变量it,因此您不必传递匿名函数。 anaphoric versionsplit-string的简单包装,s-split按换行符分隔字符串。

答案 2 :(得分:2)

这是一个简单的基于正则表达式的解析器,可以作为开始实现你想要的东西:

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