可在‘各处’工作的正则表达式

Hacker News Top 工具

摘要

本文讨论了正则表达式在sed、awk、grep和Emacs等工具之间移植的挑战,并提供了一组在这些环境中可靠工作的正则表达式子集。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/28 01:52

# “处处工作”的正则表达式 来源:https://www.johndcook.com/blog/2026/06/23/regex-everywhere/ 正则表达式最令人沮丧的一点是不同实现各有差异。一个工具支持的功能,在另一个工具中可能完全不支持,或者虽支持但语法略有不同。 我最初是在 Perl 的环境中学习正则表达式的,那是一个极致的正则表达式环境。这导致当我期望某些功能能用时,却发现它们缺失了 [1]。一种解决方法是使用 Perl 的模拟工具(https://www.johndcook.com/blog/2013/08/20/perl-as-a-better/)来替代其他工具,但这非常不标准。我希望能够向同事和客户发送开箱即用的代码。 正如我在关于计算生存主义(https://www.johndcook.com/blog/2019/10/09/computational-survivalist/)的文章中提到的,我偶尔需要在无法安装软件的计算机上工作。因此,更好的方法是找出一个“处处工作”的正则表达式功能子集。你对“处处”的定义越严格,包含的内容就越少。最严格的子集是: - 字面量 - 字符类 `\[...\]` - 特殊字符 `\. \* ^ $` 更宽松的“处处”定义,是指你最关心的那些工具。目前我最常使用正则表达式的工具是 sed、awk、grep 和 Emacs。 ## 以 Awk 作为最小公分母 如果你使用的是 Gnu 版本的 sed、awk 和 grep,并且在 sed 和 grep 中使用 `-E` 选项,那么共同支持的功能就会更多。这三个工具的正则表达式功能类似,awk 的功能在其他两个工具中也都支持,但有一个例外:awk 中的单词边界使用 `\\<` 和 `\\>`,而不是 `\b` 和 `\B`。 我在这里(https://www.johndcook.com/blog/awk-regular-expressions/)写过关于 Awk 正则表达式功能的文章。 ## Emacs 是异类 Emacs 支持大多数 awk 正则表达式功能的模拟。然而,字符 ``` + ? ( ) { } | ``` 都需要在前面加上反斜杠,才能起到与 awk 中对应的作用。另外,awk 中的 `\\s` 和 `\\S` 在 Emacs 中对应的写法是 `\\s-` 和 `\\S-`。 在 Emacs 中,`\\s` 和 `\\S` 不是表示空格或非空格,而是开始一个(取反的)字符类,其中 `-` 表示空格。但还有很多其他字符类。例如,`\\s.` 表示标点字符,`\\S.` 表示非标点字符。 ## 处处工作的功能 因此,根据我对“处处”的定义,并加上上述注意事项,以下功能是处处工作的。你的情况可能有所不同。 ``` . ^, $ [...], [^...] * \w, \W, \s, \S \1 - \9 反向引用 \b \B ? + | 分支 {n,m} 用于计数匹配 (...) 捕获分组 ``` 一个脚注:gawk 在替换字符串中支持反向引用,但在正则表达式本身中不支持。 [1] 在某种程度上,Perl 的基本功能在其他地方也能用,而高级功能则不行,这取决于你对“基本”和“高级”的看法。我把前瞻/后顾(https://www.johndcook.com/blog/2014/05/01/look-behind-regex/)视为高级功能,这没问题。但我觉得 `\d` 表示数字是基本功能,然而在许多正则表达式方言中并不支持。

相似文章

推荐一下……理解 Emacs 的模式

Lobsters Hottest

文章解释了 Emacs 的架构模式,重点介绍了通用缓冲区数据模型和增量补全读取(ICR),并将其比作玫瑰的根与花瓣。文章强调了 Emacs 如何统一界面并通过 Elisp 实现可扩展性。