正则表达式
1.概览
正则表达式由两个基本组成部分:一般字符和特殊字符。一般字符指的是任何没有特殊意义的字符。特殊字符成为元字符,如下表所示。某些情况下,特殊字符也会被视为一般字符。
字符 | BRE/ERE | 含义 |
---|---|---|
\ | both | 用来关闭后续字符的特殊含义,或者开启后续字符的特殊含义。比如\(...\) 与\{...\} |
. | both | 匹配任何非空的单个字符 |
* | both | 匹配在它之前任何数目(或没有)的单个字符。ERE而言,前置字符可以是正则表达式 |
^ | both | 锚点,表示接下来的正则表达式处于字符串或行的起始位置 |
$ | both | 锚点,表示前面的正则表达式处于字符串或行的结尾处 |
[...] | both | 方括号表达式,匹配方括号内任一字符,连字符- 指的是连续的字符范围,^ 置于括号中第一个字符时表示取字符补集。 |
\{n,m\} | BRE | 区间表达式,匹配它前面的单个字符重现的次数区间。\{n\} 指的是重现n次,而\{n,m\} 为重现n至m次。 |
\( \) | BRE | 用于后向引用。将\( 与\) 间的模式存储在特殊的保留空间中,以备后续引用。 |
\n | BRE | 用于后向引用。将在\( 与\) 括号内保留的第n个子串使用在此处 |
{m, n} | ERE | 属于ERE,与\{m,n\} 的效果相同 |
+ | ERE | 匹配前面正则表达式的一个或者多个实例 |
? | ERE | 匹配前面正则表达式的零个或者一个实例 |
| | ERE | 匹配|前面或者后面的正则表达式,选择关系 |
() | ERE | 匹配与括号括起来的正则表达式群,视为一个整体 |
2. 详解与示例
2.1 方括号表达式
[...]
: 匹配由…表示的字符集中的任意一个字符。
在方括号表达式中,所有除了-和】的元字符都失去特殊含义。所以[*\.]
匹配上面的星号、反斜杠和句点。要让]
进入该集合只能放在列表的最前面:[]*\.]
,这是因为列表不能为空,第一个]
不能解释为集合结束标志。要让-
进入该集合,需要将它放在列表最前端或最后端。如果需要右方括号和减号都进入集合,可以这样:[]*\.-]
。
字符集不同于方括号表达式,他表示一个由字符组成的集合。
字符集可以直接由某些字符组成,比如[abc],这里的字符集是由a,b,c组成的。
也可以是某些特殊规定的字符集:
- 以[:与:]将关键字组合括起来的POSIX字符集
- 排序符号 (不怎么用)
- 等价字符集 (不怎么用)
POSIX 字符集合:
类别 | 匹配字符集合 | 类别 | 匹配字符集合 |
---|---|---|---|
[:alnum:] | 数字与字母字符 | [:lower:] | 小写字母 |
[:alpha:] | 字母字符 | [:upper:] | 大写字母 |
[:blank:] | 空格字符 | [:print:] | 可显示的字符 |
[:cntrl:] | 控制字符 | [:punct:] | 标点符号 |
[:digit:] | 数字字符 | [:space:] | 空白字符 |
[:graph:] | 非空格字符 | [:xdigit:] | 十六进制数字 |
比如:
[[:alpha:]!]
匹配任一英文字母或者惊叹号
[[:cntrl:]]
匹配任一控制字符
2.2 基本正则表达式(BRE)
2.2.1 匹配单个字符
- 一般字符指的是除了元字符之外的字符,一般字符所表示的就是他们自己。
- 若meta字符不能表示他们自己,可以中\转义来表示他。若反斜杠放在一般字符前,POSIX标准保留此行为模式为未定义。
.
字符意即任意字符。- 方括号表达式。在方括号表达式里,
^
放在字首表示取补集。
模式 | 匹配的字符串 |
---|---|
a | only a |
\\ | only \ |
\* | only * |
. | a , b , e |
[a-e] | a ,b ,c ,d ,e |
[:upper:] | : , u , p , e , r |
[[:upper:]] | A , B , Z |
[]/*[:lower:][0-9A-C]-] | ] , - , a , B , * , 1 |
2.2.2 后向引用
后向引用指的是匹配于正则表达式匹配的先前的部分。使用后向引用的步骤有两个。第一步将子表达式包围在\(
和\)
里;单个模式里最多可包括9个子表达式,且可以嵌套。下一步是在同一模式内使用\1
至\9
引用之前选择的子模式,意味着此处匹配第n个之前括号内子模式匹配成功的字符(而不是重复之前的子模式)
模式 | 匹配的字符串 |
---|---|
\(['"]\).*\1 | "foo" , 'foo' ,(not 'foo" ) |
2.2.3 单个表达式匹配多个字符
- 匹配多个字符的字符串最简单的方法就是把他们一个接着一个列出来
- 修饰符
*
表示匹配0个或者多个前面的单个字符 - 区间表达式:
\{n\}
表示前置正则表达式的结果重现n次\{n,\}
前置正则表达式的结果重现至少n次\{n,m\}
前置正则表达式的结果重现n至m次
模式 | 匹配的字符串 |
---|---|
a\{3\} | aaa , aaaa |
2.2.4 文本匹配锚点
脱字符号^
与货币符号$
叫做锚点,因为他们限制模式字符串处于一行或字符串的开始和结尾。
^
和$
尽在BRE的起始和结尾处具有特殊的用途,在字符串中间时表示的就是它本身。
模式 | 匹配的字符串 |
---|---|
^foo | foofaw , fooafk |
foo$ | afoo , foo , efoo |
^foo$ | foo |
^$ | |
ab^cd$ | eab^cd , ab^cd |
2.2.5 BRE 运算符优先级
优先级由高至低
运算符 | 意义 |
---|---|
[..] ,[==] ,[::] | 用于字符排序的方括号符号 |
\meta | 转义的meta |
[] | 方括号表达式 |
(),\digit | 子表达式与后向引用 |
* , {} | 前置单个字符重现 |
无符号 | 连续 |
^ $ | 锚点 |
2.3 扩展正则表达式(ERE)
ERE拥有比基本表达式更多的功能,ERE里有些META字符看起来与BRE类似,却具有不同的意义。
2.3.1 匹配单个字符
本质上相同,meta字符集有些不同。
2.3.2 后向引用不存在
圆括号在ERE里具有特殊含义,但和BRE中有所不同。
2.3.3 匹配单个表达式或多个正则表达式
区间表达式在ERE中也是使用花括号但不需要前置反斜杠字符。
2.3.4 交替
交替运算符,是垂直的一条线,或称管道字符|
。
|
字符在ERE中优先级最低。
他的作用是匹配左边模式或者右边模式。
2.3.5 分组
圆方括号提供分组功能,整个组视为一个子模式
2.3.6 停驻文本匹配
对于^
和$
,ERE与BRE只有一个不同:在ERE里,^
和$
永远都是meta字符,所以像ab^cd
与ef$gh
这样的正则表达式仍是有效的,只是无法匹配到任何东西。同BRE,他们在方括号里失去了他们特殊的意义。
2.3.7 ERE 运算符的优先级
优先级由高至低
运算符 | 含义 |
---|---|
[..],[==],[::] | |
\meta | |
[] | 方括号表达式 |
() | 分组 |
* ,+,?,{} | 重复前置的正则表达式 |
无符号 | 连续字符 |
^,$ | 锚点 |
| | 交替 |
2.4 正则表达式的扩展
很多程序提供正则表达式的扩展。这类扩展大多采用反斜杠加一个字符,以形成新的运算符。
最常见的扩展为\<
和\>
运算符,分别匹配“单词”的开头和结尾。单词是由字母、数字和下划线组成的。
额外的GNU正则表达式运算符
运算符 | 含义 |
---|---|
\w | 匹配任何单词组成字符,等同于[[:alnum:]_] |
\W | 匹配任何非单词组成字符,等同于[^[:alnum:]_] |
\<> | 匹配单词的开头和结尾 |
\b | 匹配单词的开头或结尾处所找到的空字符串,awk用\b 表示退格,\y 表示此功能 |
\B | 表示两个单词组成字符之间的空字符串 |
\’ \` | GNU程序通常将它们视为与^ 和$ 同义 |