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

5

如何正确地解析缓冲区以存储其内容并重复使用?

假设我有这个缓冲区:

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

我成功地清除了它,但是在构建对象时(一个名为“lines”的列表,其中包含名为“words”的列表),我不知道如何做到这一点:

(list-length lines)
    ==> 4

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

有没有志同道合的人能指引我走向光明?感谢您的耐心,Lisp前辈们。


我想我找到了一种计算行数的方法。但是关于将单词存储在易于检索的形式中,没有什么好办法。 - yPhil
3个回答

8
您还可以使用内置的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的常量一元素列表的长度。


我不得不戴上墨镜才能阅读你的“sur-mesure”答案。它充满了有用的信息,非常感谢你,你是一位绅士和学者 :) - yPhil
@PhilippeCM...我不得不打开一本法语词典才知道"sur-mesure"是什么意思;-)很高兴它有帮助! - user725091

3
假设变量text包含您的缓冲区内容的字符串,参见Jon O答案。然后使用dash.el列表API和s.el API函数:
(--map (s-split "|" it) (s-lines text))

--map指代版本-map,它公开了临时变量it,因此您无需传递匿名函数。 s-split是对split-string的简单包装,s-lines通过换行符将字符串分成多行。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接