内容提要
正则表达式用于从文本中查找、校验和替换符合规则的内容。其概念源于20世纪40年代神经网络研究,50年代由Kleene提出“正则集合”。1968年Thompson提出将正则编译为自动机的算法,并催生grep等工具。80年代POSIX标准划分BRE与ERE。1986年Spencer的回溯库成为Perl、PCRE等主流实现的基础。1997年PCRE发布,2007年Google开源采用线性时间算法的RE2,2011年PCRE-JIT提升性能,2015年推出PCRE2。
延伸解读
回溯与线性时间:两种引擎路线的取舍
文章指出,1986年Spencer的库选择回溯算法,成为Perl、PCRE、Python等主流实现的祖先;而2007年开源的RE2则完全摒弃递归回溯,采用基于NFA/DFA转换的线性时间算法,强调“安全第一”。这意味着前者在功能表达上更灵活,但可能面临灾难性回溯的性能问题;后者在时间上更可控,却未必支持所有回溯特性。读者在选择工具时,需根据模式复杂度和性能要求权衡。
POSIX标准化并未终结方言差异
文章提到,1980年代POSIX将正则划分为BRE和ERE两个层级,试图为Unix工具中形形色色的正则方言建立共识。BRE中+、?、|等符号需转义才有特殊含义,ERE则无需额外转义。但POSIX所代表的“传统正则”在功能表达力上仍相对克制,后续Perl、PCRE等实现又引入了更多扩展。这说明标准化能统一基础语法,却难以覆盖所有实现的功能差异,跨工具使用时仍需留意具体方言。
从grep到PCRE2:正则实现的演进脉络
文章梳理了一条清晰的技术传承线:Thompson将正则编译为NFA的算法先用于QED和ed,其中g/regular expression/p命令独立后成为grep;Spencer的库被适配进Perl,其POSIX版本进入4.4BSD,后续ARE又被PostgreSQL继承。1997年PCRE为Exim而生,2011年PCRE-JIT提升复杂模式执行速度,2015年PCRE2推出修订API和新的性能优化选项。读者可借此理解不同工具背后可能共享同一套引擎血脉。
Q&A
正则表达式主要用来做什么?
正则表达式用于从文本中查找、校验和替换符合规则的内容。常见用途包括:从日志或文本中提取URL、IP、数字等;校验手机号、邮箱、身份证号、日期等格式;以及先找出符合规则的文本再进行替换。
正则表达式的概念最早是谁提出的?
正则表达式的概念源于20世纪40年代Warren McCulloch和Walter Pitts用数学方式描述神经网络的研究。50年代,数学家Stephen Kleene在此基础上发表了论文,描述了一种叫做“正则集合”的数学符号,首次引入了正则表达式的概念。
Thompson构造法是什么?它对正则表达式有什么影响?
Thompson构造法是1968年Ken Thompson提出的算法,能将正则表达式编译为非确定性有限自动机(NFA),实现O(mn)时间的匹配。该算法至今仍是正则引擎的核心算法之一,并催生了grep等工具。
POSIX标准中的BRE和ERE有什么区别?
POSIX将正则表达式分为两个层级:BRE(基本正则表达式)是历史更早的形态,grep、sed、vi等工具遵循此标准,其中+、?、|、(、)等符号需要转义后才具有特殊含义;ERE(扩展正则表达式)作为BRE的超集,egrep、awk等属于此列,元字符无需额外转义即可直接使用,书写更简洁。
PCRE是什么?它和Perl有什么关系?
PCRE全称Perl Compatible Regular Expressions(Perl兼容正则表达式),是1997年Philip Hazel为邮件服务器Exim开发的。它基于Perl的正则表达式语法,而Perl的正则表达式又源自Henry Spencer在1986年发布的正则库。PCRE后来成为广泛使用的正则实现之一。
RE2引擎和传统的回溯引擎有什么不同?
RE2是Google于2007年开源的引擎,它完全摒弃了递归回溯,采用基于NFA/DFA转换的线性时间算法,设计理念是“安全第一”。而传统回溯引擎(如Perl、PCRE)虽然功能强大,但可能面临灾难性回溯的性能问题。