Answers:
有多种方法可以做到这一点。可以通过以下方法使Kaushal的方法更有效:
(goto-char (point-min))
(while (not (eobp))
(let ((line (buffer-substring (point)
(progn (forward-line 1) (point)))))
...))
但是在Emacs中,更常见的是在缓冲区而不是字符串上工作。因此,您只需执行以下操作即可,而不是提取字符串然后再对其进行处理:
(goto-char (point-min))
(while (not (eobp))
...
(forward-line 1))
另外,如果您要在区域上而不是整个缓冲区上进行操作,并且如果您的“操作”包括修改缓冲区,那么经常向后进行操作(这样您就不会被“结束”这一事实所困扰。每次修改缓冲区时区域的位置都会移动”:
(goto-char end)
(while (> (point) start)
...
(forward-line -1))
(let ((start (point))) (goto-char (point-max)) (while (> (point) start) ... (forward-line -1)))
吗?
start
和end
是现有变量,它们界定了我们要操作的区域。
我不知道任何惯用的方式,但是我想到了:
(defun my/walk-line-by-line ()
"Process each line in the buffer one by one."
(interactive)
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(let* ((lb (line-beginning-position))
(le (line-end-position))
(ln (buffer-substring-no-properties lb le)))
(message ">> %s" ln) ; Replace this with any processing function you like
(forward-line 1)))))
我认为以下内容非常实用:
(dolist (line (split-string (buffer-string) "\n"))
... process line here ...
)
编辑:这是loop
替代的另一种解决方案dolist
,它还根据行是否与您的正则表达式匹配来对行进行分类:
(loop for line in (split-string (buffer-string) "\n")
if (string-match "your-regexp" line)
collect line into matching
else
collect line into nonmatching
finally return (cons matching nonmatching)
)
例如,如果将变量设置为该函数的输出 (setq x (loop ...))
,则将在其中找到所需的匹配行(car x)
列表,而不匹配的行列表为(cdr x)
。