emacs语法突出显示不属于单词的数字(使用regex?)



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

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

这是一个良好的开端,即突出显示任何数字。然而,我是regex的完全初学者,理想情况下喜欢以下行为:

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

不幸的是,这看起来很像一个"为我做这件事"的问题,我不愿意发布,但到目前为止,我自己还没有取得任何像样的进步。

据我所知,[^a-zA-Z][0-9]+[^a-zA-Z]可以与两边的字母(例如等号)之外的任何字母匹配,但这一切都只是在高亮显示中包括相邻的符号。我不知道如何告诉它"如果两边都没有字母,只突出显示数字"。

当然,我无法想象regex是处理复杂语法高亮显示的方法,所以emacs中任何好的数字高亮显示想法都是受欢迎的,

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

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

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

只需在开始使用的字符类中添加一个句点,就可以匹配浮点值,使其成为[0-9.]。不幸的是,这完全可以与一个时期相匹配;我们真正想要的是[0-9]*.?[0-9]+,它将匹配0个或多个数字,然后是一个可选的句点,再后面是一个或多个子数字。

前导符号可以与[-+]?匹配,这样我们就得到了负数。

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

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

首先,丢失add-hooklambdafont-lock-add-keywords调用也不需要。如果只想将此值用于python-mode,请将模式符号作为第一个参数而不是nil

其次,主要有两种方法。

  1. 在数字周围添加分组结构。字体锁定关键字表单中的数字对应于组,因此这将是'(("\([^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. 只需使用符号反斜杠结构的开头和结尾。然后regexp看起来像这样:_<[0-9]+_>。我们可以在这里突出显示整个比赛,因此不需要组号:'(("\_<[0-9]+\_>" . font-lock-warning-face prepend)。作为一种变体,您可以使用单词的开头和结尾结构,但您可能不想突出显示下划线附近的数字或语法类symbolpython-mode具有的任何其他字符(如果有的话)。

最后,可能不需要prepend。在此之前,这些数字可能都被取消高亮显示,如果你考虑到可能与whitespace等其他次要模式交互,你最好选择append,或者完全省略这个元素。

最终结果:

(font-lock-add-keywords nil '(("\_<[0-9]+\_>" . font-lock-warning-face)))

最新更新