Previous: 编辑中使用的标准正则表达式, Up: 搜索与匹配 [Contents][Index]
35.9 Emacs 与 POSIX 正则表达式对比 ¶
正则表达式语法在不同程序中差异很大。
在编写用于生成供其他程序使用的正则表达式的 Elisp 代码时,了解语法变体之间的区别会很有帮助。
为了体现这种差异,本节讨论 Emacs 正则表达式与 POSIX 标准化的两种语法变体有何不同:
基础正则表达式(BRE)和扩展正则表达式(ERE)。
普通的 grep 使用 BRE,‘grep -E’ 使用 ERE。
Emacs 正则表达式的语法更接近 ERE 而非 BRE,并带有一些扩展。
下面总结 POSIX BRE、ERE 与 Emacs 正则表达式的区别。
- 在 POSIX BRE 中,‘+’ 和 ‘?’ 不具有特殊含义。
唯一的反斜杠转义序列是 ‘\(…\)’、
‘\{…\}’、‘\1’ 至 ‘\9’,
以及转义特殊字符 ‘\$’、‘\*’、‘\.’、‘\[’、
‘\\’ 和 ‘\^’。
因此 ‘\(?:’ 的行为类似于 ‘\([?]:’。
POSIX 未定义其他 BRE 转义的行为;
例如,GNU
grep 对 ‘\|’ 的处理与 Emacs 相同,
但并不支持 Emacs 的全部转义。
- 在 POSIX BRE 中,‘^’ 在 ‘\(’ 之后是否特殊由实现决定;
GNU
grep 的处理方式与 Emacs 一致。
在 POSIX ERE 中,‘^’ 在括号表达式之外始终特殊,
这意味着 ERE ‘x^’ 永远无法匹配。
在 Emacs 正则表达式中,‘^’ 仅在正则表达式开头
或在 ‘\(’、‘\(?:’、‘\|’ 之后才特殊。
- 在 POSIX BRE 中,‘$’ 在 ‘\)’ 之前是否特殊由实现决定;
GNU
grep 的处理方式与 Emacs 一致。
在 POSIX ERE 中,‘$’ 在括号表达式之外始终特殊(see bracket expressions),
这意味着 ERE ‘$x’ 永远无法匹配。
在 Emacs 正则表达式中,‘$’ 仅在正则表达式末尾
或在 ‘\)’、‘\|’ 之前才特殊。
- 在 POSIX ERE 中,‘{’, ‘(’ 和 ‘|’ 是特殊字符,
‘)’ 在与前面的 ‘(’ 配对时特殊。
这些特殊字符前面不加反斜杠;
‘(?’ 会产生未定义结果。
唯一的反斜杠转义序列是转义特殊字符
‘\$’、‘\(’、‘\)’、‘\*’、‘\+’、‘\.’、
‘\?’、‘\[’、‘\\’、‘\^’、‘\{’ 和 ‘\|’。
POSIX 未定义其他 ERE 转义的行为;
例如,GNU ‘grep -E’ 对 ‘\1’ 的处理与 Emacs 相同,
但不支持 Emacs 的全部转义。
- 在 POSIX BRE 和 ERE 中,
重复运算符出现在正则表达式或子表达式开头(前面可带有 ‘^’)会产生未定义结果,
唯一例外是重复运算符 ‘*’ 在 BRE 中的行为与 Emacs 一致。
在 Emacs 中,这些运算符会被当作普通字符处理。
- 在 BRE 和 ERE 中,两个重复运算符连续出现会产生未定义结果。
在 Emacs 中,它们有明确行为,例如 ‘a**’ 等价于 ‘a*’。
- 在 BRE 和 ERE 中,空正则表达式或空子表达式会产生未定义结果。
在 Emacs 中这些行为明确,例如 ‘\(\)*’ 匹配空字符串。
- 在 BRE 和 ERE 中,命名字符类 ‘[:ascii:]’、‘[:multibyte:]’、
‘[:nonascii:]’、‘[:unibyte:]’ 和 ‘[:word:]’ 会产生未定义结果。
- BRE 和 ERE 可以在括号表达式中包含对照符号和等价类表达式,
例如 ‘[[.ch.]d[=a=]]’。
Emacs 正则表达式不支持此类写法。
- BRE、ERE 及其匹配的字符串不能包含编码错误或空字节(NUL)。
在 Emacs 中这些结构会直接匹配自身。
- BRE 和 ERE 搜索总是匹配最长可能的串。
Emacs 搜索默认并不一定如此。
See 正则表达式的最长匹配搜索。