正则表达式入门

备注

对于许多程序员来说, 正则表达式是他们用来解决任何类型的文本解析情况的某种神奇剑。但是这个工具并不神奇,即使它的功能很棒,它也不是一个全功能的编程语言( 不是图灵完备的)。

“正则表达”是什么意思?

正则表达式表达由常规语法定义的语言,该语法可以通过非确定性有限自动机 (NFA)来解决,其中匹配由状态表示。

常规语法乔姆斯基层次结构表达的最简单的语法。

乔姆斯基的等级制度

简单地说,常规语言通过NFA可以表达的内容直观地表达,这是NFA的一个非常简单的例子:

NFA示例

正则表达式语言是这种自动机的文本表示。最后一个例子由以下正则表达式表示:

^[01]*1$

哪个匹配任何以01开头的字符串,重复0次或更多次,以1结尾。换句话说,它是一个正则表达式,用于匹配二进制表示中的奇数。

所有正则表达式实际上都是常规语法吗?

实际上他们不是。许多正则表达式引擎已得到改进,并且正在使用下推式自动机 ,它可以堆叠,并在运行时弹出信息。那些自动机在乔姆斯基的层次结构中定义了所谓的无上下文语法 。非常规正则表达式中最典型的用法是使用递归模式进行括号匹配。

像下面这样的递归正则表达式(匹配括号)是这样一个实现的一个例子:

{((?>[^\(\)]+|(?R))*)}

(这个例子不使用Python的工作re引擎,但与regex引擎 ,或与PCRE引擎 )。

资源

有关正则表达式背后理论的更多信息,您可以参考麻省理工学院提供的以下课程:

当您编写或调试复杂的正则表达式时,有一些在线工具可以帮助将正则表达式可视化为自动机,例如debuggex站点

版本

PCRE

发布
2 2015年1月5日
1 1997年6月1日

使用者: PHP 4.2.0(及更高版本), Delphi XE(及更高版本), JuliaNotepad ++

Perl的

发布
1 1987年12月18日
2 1988年6月5日
3 1989年10月18日
4 1991年3月21日
1994年10月17日
6 2009-07-28

。净

发布
1 2002年2月13日
4 2010-04-12

语言: C#

Java的

发布
4 2002-02-06
2004-10-04
7 2011-07-07
SE8 2014年3月18日

JavaScript的

发布
1.2 1997年6月11日
1.8.5 2010-07-27

蟒蛇

发布
1.4 1996年10月25日
2.0 2000年10月16日
3.0 2008-12-03
3.5.2 2016年6月7日

Oniguruma

发布
初始 2002-02-25
5.9.6 2014-12-12
Onigmo 2015年1月20日

促进

发布
0 1999年12月14日
1.61.0 2016年5月13日

POSIX

发布
BRE 1997-01-01
ERE 2008-01-01

语言: Bash

角色指南

请注意,某些语法元素根据表达式具有不同的行为。

句法描述
? 匹配前面的字符或子表达式0或1次。还用于非捕获组和命名捕获组。
* 匹配前面的字符或子表达式0次或更多次。
+ 将前面的字符或子表达式匹配1次或更多次。
{n} 准确匹配前面的字符或子表达n次。
{min,} 匹配前面的字符或子表达式最少或更多次。
{,max} 最多匹配前面的字符或子表达式或更少次数。
{min,max} 匹配前面的字符或子表达式至少min次但不超过max次。
- 当包括方括号之间指示to ;例如[3-6]匹配字符3,4,5或6。
^ 字符串的开始(如果指定了multiline /m选项,则为行的开头),或者否定选项列表(即,如果在方括号[]
$ 字符串结尾(如果指定了multiline /m选项,则为行尾)。
( ... ) 组子表达式,捕获特殊变量( \1\2等)中的匹配内容,这些变量可以在以后的同一个正则表达式中使用,例如(\w+)\s\1\s匹配单词重复
(?<name> ... ) 对子表达式进行分组,并在命名组中捕获它们
(?: ...... ) 将子表达式分组而不捕获
. 匹配除换行符之外的任何字符( \n ,通常为\r \n )。
[ ... ] 这些括号之间的任何字符都应匹配一次。注意: ^在开放式括号后面否定此效果。 -在括号内发生允许指定一系列值(除非它是第一个或最后一个字符,在这种情况下它只表示常规短划线)。
\ 逃避以下角色。也用于元序列 - 具有特殊含义的正则表达式令牌。
\$ 美元(即逃脱的特殊字符)
\( 开括号(即转义的特殊字符)
\) 闭括号(即逃脱的特殊字符)
\* 星号(即逃脱的特殊字符)
\. 点(即逃脱的特殊字符)
\? 问号(即逃脱的特殊字符)
\[ 左(打开)方括号(即转义的特殊字符)
\\ 反斜杠(即转义的特殊字符)
\] 右(关闭)方括号(即逃脱的特殊字符)
\^ 插入符号(即逃脱的特殊字符)
\{ 左(打开)花括号/括号(即转义的特殊字符)
\| 管道(即逃脱的特殊字符)
\} 右(关闭)花括号/大括号(即逃脱的特殊字符)
\+ 加(即逃脱的特殊字符)
\A 一个字符串的开头
\Z 一个字符串的结尾
\z 字符串的绝对值
\b 单词(字母数字序列)边界
\1\2对以前匹配的子表达式的反向引用,按()分组, \1表示第一个匹配, \2表示第二个匹配等。
[\b] 退格 - 当\b在字符类( [] )内部匹配退格时
\B 否定\b - 匹配双字符之间的任何位置以及两个非单词字符之间的任何位置
\D 非数字
\d 数字
\e 逃逸
\f 形式饲料
\n 换行
\r 回车
\S 非空白
\s 空白
\t 标签
\v 垂直标签
\W 无字
\w 单词(即字母数字字符)
{ ... } 命名字符集
| 要么;即描述先前和先前的选项。