正则表达式:regular expression(Regex),用以匹配和处理文本的字符串,查找和替换特定信息的工具。
[TOC]
-
纯文本:直接使用要匹配的字符。eg--
abc
匹配到了 abc -
任意字符:任意一个单个字符:
.
。(一般不匹配换行符) -
特殊字符:转义符:
\
(\.
匹配 .\\
匹配\
自身)。
-
多个字符中的某一个:要匹配的字符集合写入
[ ]
中。 eg--·匹配aac bbc ccc 中的ac和bc:[ab]c
匹配到了 aac bbc -
字符集合区间: 一个字符到另一个字符之间使用
-
,正则里-
不需要转义。eg:1-9
a-z
A-Z
等等。 -
取非:
^
,即不匹配^
后的字符,作用于字符集和和字符集和区间。
- 特殊字符符:在正则表达式中具有特殊意义的字符,如
\
.
[ ]
等。eg--\[
匹配到了 [ - 空白元字符:匹配空白字符,见下表
元字符 | 匹配说明 |
---|---|
[\b] | 回退符(backspace键盘) |
\f | 换页符(form feed) |
\n | 换行符(new line) |
\r | 回车符(carriage return) |
\t | 制表符(tab) |
\v | 垂直制表符(vertical tab) |
\r\n
是一个回车加换行组合,有的操作系统(如windows)使用它作为文本行的结束标签(结束上段文本并添加一个空白行)。
- 特定字符类别
元字符 | 匹配说明 | 等价表达式 |
---|---|---|
\d | 数字(digit) | [0-9] |
\D | 非数字 | [^0-9] |
\w | 数字、字母或下划线(word) | [a-zA-Z0-9_] |
\W | 非字母、数字或下划线 | [^a-zA-Z0-9_] |
\s | 空白字符(white space) | [\f\n\r\t\v] |
\S | 非空白字符 | [^\f\n\r\t\v] |
\x | 十六进制(hexadecimal digit) | |
\0 | 八进制(Octal digit) |
-
匹配到字符的个数:
-
?
匹配到零个或一个字符(或字符集和):字符(或字符集和)的零次或一次重复。(0 or 1) -
+
匹配到一个或多个字符(或字符集和):字符(或字符集和)的一次或多次重复。(1+,无上限) -
*
匹配到零个或多个字符(或字符集和):字符(或字符集和)的零次或多次重复。(0+,无上限)
-
-
匹配要重复次数(number表示数字):
-
{number}
精确的重复次数:精确匹配number次。 -
{number1,number2}
区间内的重复次数:至少匹配number1次,至多匹配number2次。 -
{number,}
至少重复次数:至少重复number次。(次数无上限)
- 防止过度匹配
无上限的匹配字符是一种“贪婪型”元字符(尽可能多地匹配),“贪婪型”元字符加上?
就成了“懒惰型”版本(尽可能少地匹配):*?
+?
{number,}?
- 单词边界
-
\b
:匹配某单词的边界(限定单词的开始和结尾,划定\w相匹配的字符的边界);
eg--匹配The cat scattered its food中的cat(猫,排除掉scattered)这个词:\bcat \b
(注意:cat后有空格) -
\B
: 不匹配某单词的边界。 eg--\B - \B
将匹配一个前后都不是单词的连字符。(因为空格和连字符都不是数字、字母或者下划线,即不属于\w
)
- 字符串边界
定义字符开始:
^
;定义字符串结尾:$
许多正则表达式支持使用一些特殊元字符去改变另外一些元字符的行为,例如:
分行匹配模式(multiline mode)的**(? m)**记号,使得正则表达式引擎把行分隔符当作一个字符串分隔符来对待。
eg--(? m)^\s*//.*$
匹配每一行的//及其后面(仅本行)的字符
-
子表达式 把正则表达式中某一部分划为一个独立元素进行使用。把子表达式放到圆括号
()
之中。 eg--欲匹配两个到多个非折行空格(non-breaking space),即
,如果使用 {2,}
,其匹配的结果是 ;;;
这样的文本,因为{2,}
是紧挨着;
的,应该使用:( ){2,}
,将
作为一个独立的元素。 -
子表达式的嵌套 eg--匹配合法ip地址(数字,0.0.0.0-255.255.255.255,.分隔的每一个区段最大数字是255)。
(((\d{1,2})|(1\d{2})|(2[0-4)\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))
\d{1,2}
匹配一位数或者两位数(0-99);
1\d{2}
匹配1开头的三位数(100-199);
2[0-4]\d
匹配200-249;
25[0-5]
匹配250-255;
回溯引用:正则表达式中,后面的部分引用了在前面已经定义的子表达式。
不同语言有不同的写法(如(number),$number,[number],\number),此处以\number
为示例(number是一个自然数,当number为0,表示引用表达式本身)。
eg--匹配html文件中的h1-h6,如果使用<[hH][1-6]>.*?</[hH][1-6]>
则会匹配到 <h1>一级标题</h2>
这种情况;
利用回溯:<[hH]([1-6])>.*?</[hH]\1>
,将会在在</[hH]
后引用前面已经匹配好的数字,达到前后一致。
*命名捕获: 由于Number是对应固定的子表达式位置,如有改动则发生匹配偏差,一种名命名捕获的新的表达式实现出现了,它给子表达式以特殊命名,以示区分。目前此种实现未得到广泛支持。
-
回溯引用用于替换 简单的替换一般无需正则表达式,在复杂的场合,可先用一个正则表达式找出要替换上的内容,再用一个正则表达式利用回溯引用的简洁替换。
-
大小写转换
元字符 | 说明 |
---|---|
\E | 结束\L或\U转换 |
\l | 把下一个字符转换为小写 |
\L | 把\L的\E之间的字符全部转换为小写 |
\u | 把下一个字符转换为大写 |
\U | 把\U到\E之间的字符全部转换为大写 |
包含匹配的本身仅用于确定正确的匹配位置,匹配本身并不作为匹配结果的一部分返回。前后查找返回的结果是0字节,因此,又名零宽度(zero-width)匹配操作。
负前后查找相等于(正)前后查找取非,将=
换成!
。
操作符 | 说明 |
---|---|
(?=) |
(正)向前查找 |
(?!) |
负向前查找 |
(?<=) |
(正)向后查找 |
(?<!) |
负向后查找 |
eg--向前查找:
http://http.http.http/ ftp://ftp.ftp.ftp/
要匹配其中的通信协议(即http ftp),.+(?=:)
自:向前匹配到http和ftp而不包括:本身。
向后查找:
eg--要匹配一份商品售价单中的价格(数字) tamato:$1 potato$:1.5
,(?<=\$)[0-9.]+
匹配到1和1.5。
正则表达式中有时需要嵌入一定的条件进行匹配。嵌入条件用?(条件)
。条件可以是一个子表达式,也可以是一个回溯引用的序列数字,即相应的回溯引用子表达式的位置)
--eg:将一段html中的<img>
标签全部找出来,如果<img>
是个链接(即<img>
位于 <a></a>
中),还需要将整个链接标签匹配出来。
(<[aA]\s)+[^>]+>\s*)?<[iI][mM][gG]\s+[^>]+>(?(1)\s*</[aA]>)
(<[aA]\s)+[^>]+>\s*)?
匹配<a>
或<A>
及其任意属性(如果有);
<[iI][mM][gG]\s+[^>]+>
匹配<img>
或 <IMG>
及其属性(如果有);
(?(1)\s*</[aA]>)
是回溯引用条件,?(1)
指第一个回溯引用(?(1)中的1前面可以不加\转义),如果<a>
或 <A>
存在,才利用\s*</[aA]>
匹配</a>
或</A>
。
-POSIX字符类
正则表达式实现支持的一种方式,支持的如vim,grep,python,不支持的如JavaScript。
字符类 | 匹配说明 | 等价表达式 |
---|---|---|
[:alnum:] | 字母或数字 | [a-zA-Z0-9] |
[:alpha:] | 字母 | [a-zA-Z] |
[:lower:] | 小写字母 | [a-z] |
[:upper:] | 大写字母 | [A-Z] |
[:digit:] | 数字 | [0-9] |
[:blank:] | 空格或制表符 | [\t ] (t后有一个空格) |
[:cntrl:] | ASCII控制字符(ASCII 0到31及ASCII 127) | |
[:graph:] |
同[:print:] | [:print:] |
[:print:] | 可打印字符 | |
[:punct:] | 既不属于[:alnum:]也不属于[:cntrl:]的字符 | |
[:space:] | 空白(包括空格) | [^\f\n\r\t\v] |
[:xdigit:] | 十六进制数字 | [a-fA-F0-9] |