35.3.2 复杂正则表达式示例

下面是一个复杂的正则表达式,Emacs 曾用它来识别句子结尾及其后的任意空白字符。(如今 Emacs 使用由 sentence-end 函数生成的、与之类似但更复杂的默认正则表达式。See 编辑中使用的标准正则表达式。)

下文会先以 Lisp 语法字符串形式展示该正则表达式(用于区分空格与制表符),然后展示其求值结果。字符串常量以双引号开头和结尾。‘\"’ 表示作为字符串一部分的双引号,‘\\’ 表示作为字符串一部分的反斜杠,‘\t’ 表示制表符,‘\n’ 表示换行符。

"[.?!][]\"')}]*\\($\\| $\\|\t\\|  \\)[ \t\n]*"
     ⇒ "[.?!][]\"')}]*\\($\\| $\\|  \\|  \\)[
]*"

在输出结果中,制表符和换行符会以自身形式显示。

该正则表达式连续包含四个部分,可按如下方式解读:

[.?!]

模式的第一部分是一个方括号表达式,匹配三个字符中的任意一个:句号、问号和感叹号。匹配必须以这三个字符之一开始。(这是 Emacs 现在使用的新默认正则表达式与旧版的区别之一。新的表达式还允许某些非 ASCII 字符作为句子结尾,且后面无需跟任何空白。)

[]\"')}]*

模式的第二部分匹配句号、问号或感叹号之后可能出现的任意右括号和引号,数量为零个或多个。\" 是字符串中表示双引号的 Lisp 语法。末尾的 ‘*’ 表示紧邻其前的正则表达式(本例中为方括号表达式)可以重复零次或多次。

\\($\\| $\\|\t\\|  \\)

模式的第三部分匹配句子结尾后的空白:行尾(可以带一个空格)、制表符或两个空格。双反斜杠将括号和竖线标记为正则表达式语法;括号用于限定分组,竖线用于分隔备选分支。美元符号用于匹配行尾。

[ \t\n]*

最后,模式的第四部分匹配超出句子结尾所需最小空白之外的任意额外空白。

rx 表示法中(see rx 结构化正则表达式表示法),该正则表达式可以写作:

(rx (any ".?!")                    ; 标记句子结尾的标点。
    (zero-or-more (any "\"')]}"))  ; 闭合引号或括号。
    (or line-end
        (seq " " line-end)
        "\t"
        "  ")                      ; 两个空格。
    (zero-or-more (any "\t\n ")))  ; 可选的额外空白。

由于 rx 正则表达式只是 S-表达式,它们可以像这样进行格式化和添加注释。