4

我最近搬到了 emacs,我习惯/喜欢突出显示的数字。我从这里获得的快速破解将以下内容放入我的.emacs

(add-hook 'after-change-major-mode-hook
      '(lambda () (font-lock-add-keywords 
                   nil 
                   '(("\\([0-9]+\\)" 
                      1 font-lock-warning-face prepend)))))

这提供了一个良好的开端,即突出显示任何数字。但是,我是一个完整的正则表达式初学者,理想情况下会喜欢以下行为:

  • 如果它是浮点数的一部分,也要突出显示小数点,例如 12.34
  • 如果它是单词的下一个/部分,请不要突出显示数字的任何部分。例如在这些情况下: foo11 ba11r 11spam,不应突出显示任何'1'
  • 允许在两个数字整数内使用“e”以允许科学记数法(非必需,奖励学分)

不幸的是,这看起来很像一个我不愿意发布的“为我做这个”问题,但到目前为止我自己还没有取得任何体面的进展。

据我所知,发现[^a-zA-Z][0-9]+[^a-zA-Z]除了字母以外的任何东西都可以匹配(例如等号),但这所做的只是在突出显示中包含相邻的符号。我不知道如何告诉它“如果两边都没有字母,则仅突出显示数字”。

当然,我无法想象正则表达式是复杂语法突出显示的方式,因此也欢迎任何好的数字突出显示在 emacs 想法中,

非常感谢任何帮助。(如果有任何区别,这是在 Python 编码时使用的。)

4

2 回答 2

6

首先转到您的暂存缓冲区并输入一些测试文本。放一些数字,一些包含数字的标识符,一些缺少部分的数字(如.e12)等。这些将是我们的测试用例,让我们快速进行实验。现在运行M-x re-builder以进入正则表达式构建器模式,这将让您针对当前缓冲区的文本尝试任何正则表达式以查看它匹配的内容。这是一个非常方便的模式;您将可以一直使用它。请注意,因为 Emacs lisp 要求您将正则表达式放入字符串中,所以您必须将所有反斜杠加倍。你已经正确地做到了,但我不会在这里把它们加倍。

因此,将匹配限制为不属于标识符的数字非常容易。\b 将匹配单词边界,因此在正则表达式的任一端放置一个将使其匹配整个单词

您可以通过在您开始使用的字符类中添加一个句点来匹配浮点数,使其变为[0-9.]. 不幸的是,这可以完全匹配一个时期。我们真正想要的是[0-9]*\.?[0-9]+,它将匹配 0 个或多个数字,后跟一个可选的句点,后跟一个或多个数字。

前导符号可以与 匹配[-+]?,因此得到负数。

为了匹配指数,我们需要一个可选的 group: \(...\)?,因为我们只使用它来突出显示,实际上不需要分离组的内容,我们可以这样做\(?:...\),这将节省正则表达式匹配器的时间。在组内,我们需要匹配一个“e”([eE])、一个可选符号([-+]?)和一个或多个数字([0-9]+)。

把它们放在一起:[-+]?\b[0-9]*\.?[0-9]+\(?:[eE][-+]?[0-9]+\)?\b。请注意,我已将可选符号放在第一个单词边界之前,因为“+”和“-”字符创建了单词边界。

于 2013-02-20T13:47:46.590 回答
5

首先,丢掉add-hooklambdafont-lock-add-keywords通话也不需要。如果您只希望它用于python-mode,请将模式符号作为第一个参数而不是nil.

其次,有两种主要方法可以做到这一点。

  1. 在数字周围添加一个分组结构。font-lock-keywords 表单中的数字对应于组,所以这将是'(("\\([^a-zA-Z]\\([0-9]+\\)[^a-zA-Z]\\)" 2 font-lock-warning-face prepend). 但是,外部分组在这里相当无用,因此可以简化为'(("[^a-zA-Z]\\([0-9]+\\)[^a-zA-Z]" 1 font-lock-warning-face prepend).

  2. 只需使用符号反斜杠结构的开头和结尾。然后正则表达式看起来像这样:\_<[0-9]+\_>. 我们可以在此处突出显示整场比赛,因此不需要组号:'(("\\_<[0-9]+\\_>" . font-lock-warning-face prepend)。作为一种变体,您可以使用词首和词尾结构,但您可能不想突出显示与下划线相邻的数字或python-mode语法 class 中具有的任何其他字符(如果有) symbol

最后,可能不需要prepend. 在此之前这些数字可能都未突出显示,如果您考虑与其他次要模式(如 )的可能交互whitespace,您最好选择append,或者完全省略此元素。

最终结果:

(font-lock-add-keywords nil '(("\\_<[0-9]+\\_>" . font-lock-warning-face)))
于 2013-02-20T13:34:41.733 回答