emacs语法高亮数字不是单词的一部分(使用正则表达式?)

时间:2013-02-20 12:35:02

标签: regex emacs syntax-highlighting

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

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

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

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

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

据我所知,发现[^a-zA-Z][0-9]+[^a-zA-Z]可以匹配除了字母之外的任何字母(例如等号),但所有这一切都包括突出显示中的相邻符号。我不知道怎么说它“只有在任何一方都没有信件时才会突出显示数字”。

当然,我无法想象正则表达式是复杂语法高亮的方式,所以欢迎在emacs创意中强调任何数字突出显示,

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

2 个答案:

答案 0 :(得分:6)

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

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

只需在您开始使用的字符类中添加句点,即可匹配浮点数,使其成为[0-9.]。不幸的是,这可以匹配它自己的所有时期;我们真正想要的是[0-9]*\.?[0-9]+,它将匹配0个或更多个数字,后跟一个可选的句点,后跟一个或多个数字。

一个主要标志可以与[-+]?匹配,这样我们就会得到负数。

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

全部放在一起:[0-9]+。请注意,我在第一个单词边界之前放置了可选符号,因为“+”和“ - ”字符会创建一个单词边界。

答案 1 :(得分: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. 只需使用beginning and end of symbol反斜杠结构。然后regexp看起来像这样:\_<[0-9]+\_>。我们可以在这里突出显示整个匹配项,因此不需要组号:'(("\\_<[0-9]+\\_>" . font-lock-warning-face prepend)。作为变体,您可以使用单词的开头和单词结构,但您可能不希望突出显示与下划线相邻的数字或任何其他字符(如果有),python-mode在语法课symbol

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

    最终结果:

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