12.1 sentence-end 对应的正则表达式

符号 sentence-end 绑定到表示句子结尾的模式。该正则表达式应该是什么样的?

显然,句子可以由句号、问号或感叹号结尾。实际上在英语中,只有以这三个字符之一结尾的分句才被视为句子结束。这意味着该模式应包含字符集:

[.?!]

但我们不希望 forward-sentence 只是跳转到句号、问号或感叹号,因为这些字符可能出现在句子中间。例如句号常用于缩写之后。因此还需要其他信息辅助判断。

按照惯例,句子末尾需要输入两个空格,而句子内部的句号、问号或感叹号后只输入一个空格。因此,句号、问号或感叹号后跟两个空格是句子结束的良好标志。但在文件中,这两个空格也可能是制表符或行尾。这意味着正则表达式需要将这三种情况作为备选。

这组备选形式如下:

\\($\\| \\|  \\)
       ^   ^^
      TAB  SPC

其中 ‘$’ 表示行尾,我已标注出表达式中的制表符与两个空格的位置。两者均通过直接输入实际字符插入表达式。

括号与竖线前需要两个反斜杠 ‘\\’:第一个反斜杠用于在 Emacs 中转义后续反斜杠,第二个反斜杠表示后续字符(括号或竖线)为特殊符号。

此外,句子后可能跟随一个或多个回车符,如下所示:

[
]*

与制表符和空格类似,回车符通过直接输入字面量插入正则表达式。星号表示 RET 可重复零次或多次。

但句子结尾并非仅由句号、问号或感叹号加合适空格构成:闭合引号或闭合括号等符号可能出现在空格之前。实际上可能有多个此类符号。这部分对应的表达式如下:

[]\"')}]*

该表达式中,第一个 ‘]’ 是表达式的首个字符;第二个字符是 ‘"’,前面加反斜杠 ‘\’ 告知 Emacs 该 ‘"’ 并非特殊字符。最后三个字符为 ‘'’、‘)’ 与 ‘}’。

综合以上内容,即可得到匹配句子结尾的正则表达式模式;实际上,对 sentence-end 求值会返回如下值:

sentence-end
     ⇒ "[.?!][]\"')}]*\\($\\|     \\|  \\)[
]*"

(当然,GNU Emacs 22 中并非如此;这是为了简化处理流程并支持更多字形与语言。当 sentence-end 的值为 nil 时,会使用函数 sentence-end 定义的值。(这体现了 Emacs Lisp 中变量值与函数的区别。)该函数返回由变量 sentence-end-basesentence-end-double-spacesentence-end-without-periodsentence-end-without-space 构造的值。关键变量为 sentence-end-base,其全局值与上述描述类似,但额外包含两种引号(弯引号)。变量 sentence-end-without-period 为真时,会告知 Emacs 句子可以不以句号结尾,例如泰语文本。)