正则表达式
什么是正则表达式
Regular Expression (简称 regexp 或 regex 或 re)
Regular adj. 常规的 规则的 有规律的
Expression n. 表达式
RegExp 的作用是从文本中找出符合规则的内容
常见用途:
- 查找内容:从日志、文本中提取 URL、IP、数字等
- 校验格式:手机号、邮箱、身份证号、日期等
- 能找出合规则的文本就是符合格式的
- 替换内容:替换符合规则的文本
- 先找出符合规则的文本然后再替换
- 纯粹的 RegExp 是没有替换的,替换都是由编程语言或工具实现的
正则表达式的发展历史
20 世纪 40 年代,两位神经生理学家 Warren McCulloch 和 Walter Pitts, 研究出了一种用数学方式来描述神经网络的方法,可以将神经系统中的神经元描述成小而简单的自动控制元。 1943年Warren S. McCulloch(神经科学家)与 Walter Pitts(逻辑学家)发表的基础性论文《A Logical Calculus of the Ideas Immanent in Nervous Activity》。
50 年代,一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了《神经网络事件表示法和有穷自动机》 论文。 这篇论文描述了一种叫做 "正则集合(Regular Sets)" 的数学符号,引入了正则表达式的概念。 1951年12月15日由美国兰德公司发布的编号为RM-704的研究备忘录《神经网与有限自动机中的事件表示》,是一篇在计算机科学领域具有里程碑意义的学术报告。在这篇由斯蒂芬·科尔·克莱尼撰写的报告中,首次提出了正则表达式与有限自动机的数学概念。 1956 年收入《Automata Studies》后广泛传播
1968年,肯·汤普逊(Ken Thompson)在《ACM通讯》上发表了 《正则表达式搜索算法》 一文,描述了一种将正则表达式编译为 IBM 7094 机器码、用于在文本中定位匹配字符串的方法。这篇论文所提出的Thompson 构造法,能将正则表达式转换为非确定性有限自动机(NFA),并实现 O(mn)O(mn) 时间的匹配,至今仍是正则引擎的核心算法之一。
汤普逊首先将这一能力植入文本编辑器QED,随后又带入 Unix 的编辑器ed。ed 中有一个命令 g/regular expression/p(全局搜索并打印匹配行),其功能被独立出来,便成了 Unix 中最著名的文本搜索工具 grep——“grep”这个名字本身就来自该命令的缩写。
进入1970年代,Unix 生态中涌现出更多携带正则能力的工具。由于最初的 grep 功能有限,阿尔弗雷德·阿霍(Alfred Aho)开发了增强版的 egrep,引入了 +、? 和更灵活的分组与选择操作。与此同时,sed、awk、lex 等工具也各自实现了正则表达式,但它们支持的语法并不统一,这为后来的标准化埋下了伏笔。
1980年代,POSIX(可移植操作系统接口)标准的出现试图为 Unix 工具中形形色色的正则方言建立共识。POSIX 将正则表达式划分为两个层级: BRE(基本正则表达式) :历史更早的形态,grep、sed、vi 等工具遵循此标准。在 BRE 中,+、?、|、(、) 等符号需要转义后才具备特殊含义。 ERE(扩展正则表达式) :作为 BRE 的超集,egrep、awk 等属于此列。元字符无需额外转义即可直接使用,书写上更为简洁。 POSIX 标准在一定程度上统一了 Unix 世界的正则语法,但它所代表的“传统正则”路线,在功能表达力上仍然相对克制。
1986年,Henry Spencer发布了他编写的正则表达式库,这是一个高质量、公开发布的C语言实现 核心算法选择了回溯(backtracking) 这个库迅速被广泛采用,并成为了后来一系列主流正则表达式实现的直接祖先。 今天使用最广的、基于回溯的“慢速”实现——Perl、PCRE、Python 等——其技术血脉都可以追溯到这个1986年的库。
perl Practical Extraction and Report Language 实用 提取 和 报告 语言 Larry Wall 在 1987 发布了 perl,将正则表达式深度集成到语言中 Larry Wall 在1987年12月18日把1.0版本发布到了comp.sources.misc新闻组。 关于Perl名字的由来,有很多说法。虽然Perl不是正式的首字母缩略词,但仍有各种各样的逆向首字母缩略词,包括“实用的提取和报告语言”。 Perl原名叫“Pearl(珍珠)”。拉里·沃尔想给这个语言起一个有正面意思的短的名字;他考虑了(并且否定了)字典里每一个3—4个字母的词。他也考虑用他的妻子Gloria的名字命名。沃尔在Perl官方发布之前发现了已存在PEARL语言,为了防止混淆,沃尔才把它改名Perl。 Larry Wall将Spencer的库适配进Perl(1988年),以改进现有正则。
大约在1993年,Henry Spencer根据 POSIX 标准编写了第二个版本的正则表达式库,并捐赠给了 4.4BSD。这个版本实现了 POSIX 1003.2 所定义的正则表达式接口(regcomp、regexec 等),并被描述为 “POSIX.2 兼容”。 在POSIX实现之后,Spencer 又为 Tcl 语言编写了正则表达式引擎,其成果被称为 “高级正则表达式”(Advanced Regular Expressions, ARE)。ARE 的设计目标是在POSIX 1003.2的基础上,吸收一部分Perl 5的扩展特性,从而在保持标准兼容性的同时,获得更强的表达力 ARE 的影响同样深远。PostgreSQL 的正则表达式库就直接继承自 Tcl 的 ARE 实现。 MySQL(在8.0.4之前)也曾使用他的正则表达式库。 Tcl 语言中的高级正则表达式(Advanced Regular Expressions,简称 ARE)是在 1999 年 4 月 30 日 随着 Tcl/Tk 8.1 正式版的发布而首次引入
pcre Perl Compatible Regular Expressions Perl 兼容正则表达式 1997 年,Philip Hazel 为邮件服务器 Exim 开发了 PCRE(Perl Compatible Regular Expressions)
Google于2006年开始使用并最终在2007年开源了RE2引擎,它代表了一种全新的设计理念:“安全第一” 。 RE2完全摒弃了递归回溯,转而采用基于NFA/DFA转换的线性时间算法。
为了应对回溯引擎的性能瓶颈,JIT(即时编译) 技术被引入 PCRE 生态,PCRE-JIT 于2011年出现,显著提升了复杂模式下的执行速度
2015年,PCRE项目推出了PCRE2,它提供了一个经过修订的API,并引入了诸如即时编译等新的性能优化选项
灾难性回溯 Unicode整合
正则表达式的风格和引擎
风格 POSIX BRE POSIX ERE GNU BRE GNU ERE PCRE