正则表达式基础
概述
正则表达式,英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。
正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在 Perl 中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由 UNIX 中的工具软件(例如sed
和grep
)普及开的。
简单的说形式和功能上,正则表达式和我们前面讲的通配符很像,不过它们之间又有很大差别,特别在于一些特殊的匹配字符的含义上。
假设我们有这样一个文本文件,包含 shiyanlou 和 shilouyan 这两个字符串,同样一个表达式:
shi*
如果这作为一个正则表达式,它将只能匹配 shi,而如果不是作为正则表达式 *
作为一个通配符,则将同时匹配这两个字符串。这是为什么呢?
因为在正则表达式中 *
表示匹配前面的子表达式
(这里就是它前面一个字符)零次或多次,比如它可以匹配 sh,shii,shish,shiishi 等等,而作为通配符表示匹配通配符后面任意多个任意字符,所以它可以匹配 shiyanlou 和 shilouyan 两个字符。
基本语法
一个正则表达式通常被称为一个模式
(pattern),为用来描述或者匹配一系列符合某个句法规则的字符串。
- 选择
|
竖直分隔符表示选择,例如 boy|girl
可以匹配 boy 或者 girl。
- 数量限定
数量限定除了我们举例用的 \*
还有 +
加号 ?
问号,如果在一个模式中不加数量限定符则表示出现一次且仅出现一次:
+
表示前面的字符必须出现至少一次(1 次或多次),例如 goo+gle
可以匹配 gooogle,goooogle 等;
?
表示前面的字符最多出现一次(0 次或 1 次),例如,colou?r
,可以匹配 color 或者 colour;
*
星号代表前面的字符可以不出现,也可以出现一次或者多次(0 次、或 1 次、或多次),例如,0\*42
可以匹配 42、042、0042、00042 等。
- 范围和优先级
()
圆括号可以用来定义模式字符串的范围和优先级,这可以简单的理解为是否将括号内的模式串作为一个整体。
例如,gr(a|e)y
等价于 gray|grey
,(这里体现了优先级,竖直分隔符用于选择 a 或者 e 而不是 gra 和 ey),(grand)?father
匹配 father 和 grandfather(这里体现了范围,? 将圆括号内容作为一个整体匹配)。
- 语法(部分)
正则表达式有多种不同的风格,下面列举一些常用的作为 PCRE 子集的适用于 perl 和 python 编程语言及 grep 或 egrep 的正则表达式匹配规则:
PCRE(Perl Compatible Regular Expressions 中文含义:perl 语言兼容正则表达式)是一个用 C 语言编写的正则表达式函数库,由菲利普.海泽(Philip Hazel)编写。PCRE 是一个轻量级的函数库,比 Boost 之类的正则表达式库小得多。PCRE 十分易用,同时功能也很强大,性能超过了 POSIX 正则表达式库和一些经典的正则表达式库。
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符。 例如 n 匹配字符 n ,\n 匹配一个换行符,序列 \\ 匹配 \ ,\( 则匹配 ( 。 |
^ | 匹配输入字符串的开始位置。 |
$ | 匹配输入字符串的结束位置。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如 o{2} 不能匹配 Bob 中的 o,但是能匹配 food 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配 n 次。例如 o{2,} 不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。 |
{n,m} | m 和 n 均为非负整数,其中 n<=m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 fooooood 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 z、zo 以及 zoo。* 等价于 {0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,zo+ 能匹配 zo 以及 zoo,但不能匹配 z。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 do 或 does 中的 do。? 等价于 {0,1}。 |
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 oooo,o+? 将匹配单个 o,而 o+ 将匹配所有 o。 |
. | 匹配除 \n 之外的任何单个字符。要匹配包括 \n 在内的任何字符,请使用类似 (.|\n) 的模式。 |
(pattern) | 匹配 pattern 并获取这一匹配的子字符串。该子字符串用于向后引用。要匹配圆括号字符,请使用 ( 和 )。 |
x | y | 匹配 x 或 y。例如,“z | food”能匹配 z 或 food。“(z | f)ood”则匹配 zood 或 food。 |
[xyz] | 字符集合(character class)。匹配所包含的任意一个字符。例如,[abc] 可以匹配 plain 中的 a。其中特殊字符仅有反斜线 \ 保持特殊含义,用于转义字符。其它特殊字符如星号、加号、各种括号等均作为普通字符。脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果出现在首位则仅作为普通字符。 |
[^xyz] | 排除型(negate)字符集合。匹配未列出的任意字符。例如,[^abc] 可以匹配 plain 中的 plin。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,[a-z] 可以匹配 a 到 z 范围内的任意小写字母字符。 |
[^a-z] | 排除型的字符范围。匹配任何不在指定范围内的任意字符。例如,[^a-z] 可以匹配任何不在 a 到 z 范围内的任意字符。 |
- 优先级
优先级为从上到下从左到右,依次降低:
运算符 | 说明 |
---|---|
\ | 转义符 |
(),(?:) ,(?=),[] | 括号和中括号 |
*,+,?,{n},{n,},{n,m} | 限定符 |
^,$,\ 任何元字符 | 定位点和序列 |
| | 选择 |