在缓冲区的前 n 列中收集数字的最有效方法

Most efficient way of collecting numbers in the first n columns of a buffer

如果我有一个包含

的缓冲区
         |    inout(Ix)[] prefix() inout
         |    {
     2037|        assert(!keys.empty);
     2037|        final switch (keys.length)
         |        {
000000000|        case 1:
000000000|            return keys.at!0[];
     2037|        case 2:
         |            import std.algorithm.searching : commonPrefix;
     2037|            return commonPrefix(keys.at!0[], keys.at!1[]);
         |        }
         |    }

遍历竖线字符左侧有数字的所有行的最有效方法是什么?

re-search-forwardmatch-string 是最有效的方法吗?

你提出的已经很快了。

如果您真的非常追求速度,可以避免使用正则表达式以及 search-forward 换行符和竖线。然后调用string-to-number。值得付出努力吗?

skip-chars-forwardsearch-forward 快。

但是,只有在任务完成的情况下才是正确的。如果需要重复,事情已经不同了。 search-forward 是一个更舒适的功能。 虽然可以写入 (while (search-forward "MY-CHAR")),但 skip-chars-forward 在匹配处停止,因此需要额外的 forward-char。粗略地说,使用这样一个额外的 Emacs-Lisp 级别,skip-chars-forward 的速度优势被平衡了。由于经常需要检查 EOB,search-forward 已内置,skip-chars-forward 很快就会丢失。

如果单个字符被搜索一次,skip-chars-forward 可能是一个选项。

IMO 它需要一个基准来知道下面的表格是否比 resp 更快。一个使用 re-search-forward:

(defun stop-at-numbers-in-this-special-case ()
  (interactive)
  (while
      (and (skip-chars-forward "^|")
       (eq (char-before) 32))
    (forward-char 1)))

https://www.emacswiki.org/emacs/EmacsLispBenchmark

我选择在结果中添加行号,因为还有另一个相关的线程 - Showing D Coverage Results as Overlays in Source Buffer - 表示原始发布者想要使用结果放置叠加层等。 [原始发布者可能希望向结果添加更多内容(例如,缓冲区中的 point 位置),然后将结果和 mapc 放在列表中 - 放置叠加层before-string 属性 如果需要的话,在左边距内(在左边缘之前)。从最左边到管道的每一行的文本也可以删除(或隐藏),以便覆盖层取代已删除(或隐藏)的内容。]

(let (result)
  (save-excursion
    (goto-char (point-max))
    (while (re-search-backward "^\s?+\([0-9]?+\)|" nil t)
      (push (cons (format-mode-line "%l") (match-string 1)) result))
    result))

结果如下所示:

(("1" . "") ("2" . "") ("3" . "2037") ("4" . "2037") ("5" . "") ("6" . "000000000") ("7" . "000000000") ("8" . "2037") ("9" . "") ("10" . "2037") ("11" . "") ("12" . ""))