【问题标题】:In emacs, how to match a regexp at the end of the buffer在emacs中,如何匹配缓冲区末尾的正则表达式
【发布时间】:2016-06-10 06:16:50
【问题描述】:

在文本缓冲区中,我想检查文件是否以字符串“abc”结尾,后跟零到两个换行符(然后删除此结束字符)。

所以我需要looking-at-backwards 之类的东西,或者我想在文件末尾(而不是行尾)匹配。有什么简单的方法可以做到这一点?

【问题讨论】:

标签: regex emacs


【解决方案1】:

looking-back 是您正在寻找的向后匹配的函数

使用通用的 postifx 运算符 \{m,n\} 最多匹配 2 个换行符:

(save-excursion
  (goto-char (point-max))
  (when (looking-back "^abc\n\\{,2\\}")
    (delete-region (match-beginning 0) (match-end 0))))

【讨论】:

  • end-of-buffer 的文档字符串说明(部分):“此函数仅供交互使用;在 Lisp 代码中使用 (goto-char (point-max))”并且, beginning-of-buffer 的文档字符串状态(部分):“此函数仅供交互使用;在 Lisp 代码中使用 (goto-char (point-min))”因为将来阅读此答案的人可能倾向于以编程方式复制和延续 end-of-buffer 的使用,请考虑相应地修改您的答案。
【解决方案2】:

您所描述的内容并不需要 Emacs 中通常称为正则表达式 search 的内容。它要求在缓冲区(eob)的末尾匹配一个正则表达式。我已经相应地编辑了您的问题标题和文本。

为此,您只需暂时移动到缓冲区的末尾并使用looking-back 来检查正则表达式匹配。

(defun delete-abc-SPC-<-3-newlines ()
  "Delete `abc ' followed by up to 2 newlines at eob."
  (interactive)
  (let ((ends-w-<-3-newlines  nil))
    (save-excursion
      (goto-char (point-max))
      (setq ends-w-<-3-newlines  (looking-back "abc \n?\n?\n?")))
    (when ends-w-<-3-newlines
      (delete-region (match-beginning 0) (match-end 0)))))

如果你不希望缓冲区被认为是新修改的,那么使用这个:

(defun delete-abc-SPC-<-3-newlines ()
  "Delete `abc ' followed by up to 2 newlines at eob."
  (interactive)
  (let ((ends-w-<-3-newlines  nil)
        (mod-buf              (buffer-modified-p)))
    (save-excursion
      (goto-char (point-max))
      (setq ends-w-<-3-newlines  (looking-back "abc \n?\n?\n?")))
    (when ends-w-<-3-newlines
      (delete-region (match-beginning 0) (match-end 0)))
    (set-buffer-modified-p  mod-buf)))

【讨论】:

  • 有点像我要求的,但我确实认为@hoelzel 的回答更加简洁。
  • (1) 它更简洁,因为它不需要定义命令(以及因为这里提到的其他事情)。 (2) 在abc 之后不包括SPC,这不是你要求的。 (3) 它错误地使用了end-of-buffer(参见C-h f:“不要在 Lisp 程序中使用此命令!(goto-char (point-max)) 更快。”)。 (4) 错误地使用save-restriction 而不是save-excursion(这里不需要save-restriction)。 (5) 不恢复缓冲区修改状态。 (6) 它没有解决您对搜索与正则表达式匹配的混淆。
  • 您的一些观点非常有效,感谢您指出其他代码的问题。 @hoetzel 确实解决了他们。总的来说,我更喜欢不太详细的答案。 - 如果你想进一步讨论这个问题,我想我们应该转到讨论频道。
猜你喜欢
  • 1970-01-01
  • 2021-09-01
  • 2019-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多