正则表达式

✍ dations ◷ 2024-12-22 20:47:49 #编译原理,形式语言,程序设计语言,标记法

正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。

Regular Expression的Regular一般被译为正则、正规或常规。此处的Regular即是规则、规律的意思,Regular Expression即“描述某种规则的表达式”之意。

最初的正则表达式出现于理论计算机科学的自动控制理论和形式化语言理论中。在这些领域中有对计算(自动控制)的模型和对形式化语言描述与分类的研究。

1940年,沃伦·麦卡洛克与沃尔特·皮茨将神经系统中的神经元描述成小而简单的自动控制元。

1950年代,数学家斯蒂芬·科尔·克莱尼利用称之为“正则集合”的数学符号来描述此模型。肯·汤普逊将此符号系统引入编辑器QED(英语:QED (text editor)),随后是Unix上的编辑器ed,并最终引入grep。自此以后,正则表达式被广泛地应用于各种Unix或类Unix系统的工具中。正则表达式的POSIX规范,分为基本型正则表达式(Basic Regular Expression,BRE)和扩展型正则表达式(Extended Regular Express,ERE)两大流派。在兼容POSIX的UNIX系统上,grep和egrep之类的工具都遵循POSIX规范,一些数据库系统中的正则表达式也匹配POSIX规范。grep、vi、sed都属于BRE,是历史最早的正则表达式,因此元字符必须转译之后才具有特殊含义。egrep、awk则属于ERE,元字符不用转译

Perl的正则表达式源自于Henry Spencer(英语:Henry Spencer)于1986年1月19日发布的regex,它已经演化成了PCRE(Perl兼容正则表达式,Perl Compatible Regular Expressions(英语:PCRE)),一个由Philip Hazel(英语:Philip Hazel)开发的,为很多现代工具所使用的库。

各编程语言之间关于正则表达式的集成,目前开发进展得很差。Perl6的子项目Apocalypse的设计中已考虑到了这点。

正则表达式可以用形式化语言理论的方式来表达。正则表达式由常量和算子组成,它们分别表示字符串的集合和在这些集合上的运算。给定有限字母表Σ定义了下列常量:

定义了下列运算:

上述常量和算子形成了克莱尼代数。

很多课本使用对选择使用符号 {\displaystyle \cup } + {\displaystyle +} {\displaystyle \vee } 替代竖线。

为了避免括号,假定Kleene星号有最高优先级,接着是串接,接着是并集。如果没有歧义则可以省略括号。例如:(ab)c可以写为abca|(b(c*))可以写为a|bc*

例子:

为了使表达式更简洁,正则表达式也定义了?+aa*等于a+,表示a出现至少一次;而(a|ε)等于a?,表示a出现1次或不出现。有的定义中增加了补算子 {\displaystyle \sim } R {\displaystyle \sim R} 表示在 Σ {\displaystyle \Sigma ^{*}} 上但不在 R {\displaystyle R} 中的所有字符串的集合。补算子在理论上并非必要,因为它可以使用其他算子来表达,但它可以使一些表达式变得更加简洁。

这种意义上的正则表达式可以表达正则语言,是可被有限状态自动机精确接受的语言类。但是在简洁性上有重要区别。某类正则语言只能用大小指数增长的自动机来描述,而要求的正则表达式的长度只线性的增长。

正则表达式对应于乔姆斯基层级的类型-3文法。但通常编程语言或其相关库(例如PCRE)中实现的正则表达式的表达能力是乔姆斯基层级中类型-3文法的超集。在另一方面,在正则表达式和不导致这种大小上的爆炸的非确定有限状态自动机(NFA)之间有简单的映射;为此NFA经常被用作正则表达式的替表示式。

这种形式化中存在着冗余,典型的体现是存在不同的正则表达式可以表达同样的语言。有可能对两个给定正则表达式写一个算法来判定它们所描述的语言是否本质上相等,即简约每个表达式到极小确定有限自动机,确定它们是否同构(等价)。这种冗余可以消减到什么程度?我们可以找到仍有完全表达力的正则表达式的有趣的子集吗?这提出了一个令人惊奇的困难问题。Kleene星号和并集明显是需要的,但是我们或许可以限制它们的使用。由于正则表达式如此简单,没有办法在语法上把它重写成某种规范形式。过去公理化的缺乏导致了星号高度问题(英语:Star height problem)。最近Dexter Kozen用克莱尼代数公理化了正则表达式。

很多现实世界的“正则表达式”引擎实现了不能用正则表达式代数表达的特征。

一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列匹配某个句法规则的字符串。例如:Handel、Händel和Haendel这三个字符串,都可以由H(a|ä|ae)ndel这个模式来描述。大部分正则表达式的形式都有如下的结构:

某个字符后的数量限定符用来限定前面这个字符允许出现的个数。最常见的数量限定符包括+?*(不加数量限定则代表出现一次且仅出现一次):

上述这些构造子都可以自由组合,因此H(ae?|ä)ndelH(a|ae|ä)ndel是相同的,表示{"Handel", "Haendel", "Händel"}。

精确的语法可能因不同的工具或程序而异。

正则表达式有多种不同的风格。下表是在PCRE(英语:Perl_Compatible_Regular_Expressions)中元字符及其在正则表达式上下文中的行为的一个完整列表,适用于Perl或者Python编程语言(grep或者egrep的正则表达式文法是PCRE的子集):

在.NET、Java、JavaScript、Python的正则表达式中,可以用\uXXXX表示一个Unicode字符,其中XXXX为四位16进制数字。

Unicode字符的三种性质:

这三种Unicode性质对应的字符组补集是将开头的\p改为\P,其它不变。

相关

  • 京师同文馆京师同文馆,清末自强运动期间中国政府官办的外语人才学校,以教授西方语言为主的官办教育机构,也是中国近代最早成立的新式教育机构。京师同文馆成立于1862年8月24日,1900年停办,1
  • 沃克曼马克·塞西尔·沃克曼(英语:Mark Cecil Workman,1930年3月10日-1983年12月21日),美国篮球运动员。他在1952年NBA选秀中第1轮第1顺位被密尔瓦基老鹰选中。
  • 皮斯卡塔奎斯县皮斯卡特奎斯县(英语:Piscataquis County)是美国缅因州中部偏西的一个县,面积11,337平方公里。根据2010年人口普查,本县共有人口17,235人,是缅因州人口最少的县份。本县县治为多佛
  • 约翰一世 (法兰西)(遗腹子)约翰一世(法语:Jean Ier de France,1316年11月15日-1316年11月20日),名义上的法兰西国王和纳瓦拉国王(称胡安一世)。约翰为卡佩王朝国王路易十世的遗腹子,母亲是匈牙利公主克莱
  • 硝酸铊硝酸铊(III)是一种无机化合物,化学式为Tl(NO3)3。它通常以三水合物的形式存在。它是无色固体,剧毒。它是一种强氧化剂——其分子内的三价铊和硝酸根离子都有氧化性。它受热分解,
  • 气球藻目气球藻目(Botrydiales)为藻类植物之一植物目。该植物于植物分类表上,归于黄藻门(Xanthophyta) (Chromophyta)黄藻纲 (Xanthophyceae) ,同纲者尚有异鞭藻目(Heterochloridales)等等。
  • 迪米特尔·佩特科夫迪米特尔·佩特科夫(保加利亚语:Димитър Петков,拉丁化:Dimitar Petkov,1856年-1907年3月11日)是保加利亚人民自由党领袖成员,1906年11月5日出任保加利亚首相,1907年佩
  • 卡斯柏·古斯克卡斯柏·古斯克(丹麦语:Kasper Kusk Vangsgaard,1991年11月10日-)是一名丹麦足球员,司职中场,现效力丹麦球会哥本哈根。 以下是古斯克的职业数据︰
  • 捷连季·福米奇·什特科夫捷连季·福米奇·什特科夫(俄语:Терентий Фомич Штыков,1907年3月13日-1964年10月25日),苏联军事将领。朝鲜实际上首任最高领导人,1945年至1948年苏联对朝鲜军
  • 大宫卖神大宫卖神(オオミヤノメ)是神道的神,守护宫殿平安的女神,‘延喜式神名帐’和‘古语拾遗’表记作大宫卖神(オオミヤノメ)、伏见稻荷大社作大宫能卖大神(オオミヤノメノカミ),其他还有作