回答:
それを行うにはさまざまな方法があります。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)
ます。