正则表达式
元字符
常用的元字符 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
-
\bhi\b
: 由两个字符组成,前一个字符是h,后一个是i -
\bhi\b.*\bLucy\b
: 先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词 -
0\d{2}-\d{8}
: 以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字 -
\ba\w*\b
: 以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b) -
\d+
: 1个或更多连续的数字, 这里的+是和类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次 -
\b\w{6}\b
:匹配刚好6个字符的单词 -
^\d{5,12}$
: 5到12个数字
转义字符
如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义
-
deerchao\.cn
: 匹配deerchao.cn
-
C:\\Windows
:C:\Windows
限定符
常用的限定符 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
-
Windows\d+
: 匹配Windows后面跟1个或更多数字
字符类
[aeiou]
就匹配任何一个英文元音字母,[.?!]
匹配标点符号(.或?或!) ,[]
中括号中代表任意一个都行
-
\(?0\d{2}[) -]?\d{8}
: 匹配几种格式的电话号码 ,像(010)88886666,或022-22334455,或02912345678等。首先是一个转义字符(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。
也能匹配010)12345678或(022-87654321这样的“不正确”的格式
分枝条件
不幸的是,刚才那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。
-
0\d{2}-\d{8}|0\d{3}-\d{7}
: 匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445) -
\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}
: 匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔
使用分枝条件时,要注意各个条件的顺序,匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了
-
\d{5}-\d{4}|\d{5}
: 规则是5位数字,或者用连字号间隔的9位数字 -
\d{5}|\d{5}-\d{4}
: 只会匹配5位的数字(以及9位数字的前5位)
分组
重复多个字符,用小括号来指定子表达式
-
(\d{1,3}\.){3}\d{1,3}
:\d{1,3}
匹配1到3位的数字,(\d{1,3}\.){3}
匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})
-
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
: IP地址, 每个数字都不能大于255, 01.02.03.04 这样前面带有0的数字也是正确的
反义
取反的意思, 想查找除了数字以外,其它任意字符都行的情况
常用的反义代码 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
-
[^aeiou]
:匹配除了aeiou这几个字母以外的任意字符 -
\S+
: 不包含空白符的字符串 -
<a[^>]+>
: 用尖括号括起来的以a开头的字符串
零宽断言
代码 | 说明 |
---|---|
(?=exp) | 匹配exp前面的位置,断言自身出现的位置的后面能匹配表达式exp |
(?<=exp) | 匹配exp后面的位置,断言自身出现的位置的前面能匹配表达式exp |
(?!exp) | 匹配后面跟的不是exp的位置 |
(?<!exp) | 匹配前面不是exp的位置 |
-
\b\w+(?=ing\b)
: 匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc -
(?<=\bre)\w+\b
: 匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading -
(?<=\s)\d+(?=\s)
: 匹配以空白符间隔的数字(再次强调,不包括这些空白符)
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪*匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
懒惰限定符 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
更多
代码 | 说明 |
---|---|
\a | 报警字符(打印它的效果是电脑嘀一声) |
\b | 通常是单词分界位置,但如果在字符类里使用代表退格 |
\t | 制表符,Tab |
\r | 回车 |
\v | 竖向制表符 |
\f | 换页符 |
\n | 换行符 |
\e | Escape |
\0nn | ASCII代码中八进制代码为nn的字符 |
\xnn | ASCII代码中十六进制代码为nn的字符 |
\unnnn | Unicode代码中十六进制代码为nnnn的字符 |
\cN | ASCII控制字符。比如\cC代表Ctrl+C |
\A | 字符串开头(类似^,但不受处理多行选项的影响) |
\Z | 字符串结尾或行尾(不受处理多行选项的影响) |
\z | 字符串结尾(类似$,但不受处理多行选项的影响) |
\G | 当前搜索的开头 |
\p{name} | Unicode中命名为name的字符类,例如\p{IsGreek} |
(?>exp) | 贪婪子表达式 |
(?<x>-<y>exp) | 平衡组 |
(?im-nsx:exp) | 在子表达式exp中改变处理选项 |
(?im-nsx) | 为表达式后面的部分改变处理选项 |
(?(exp)yes|no) | 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no |
(?(exp)yes) | 同上,只是使用空表达式作为no |
(?(name)yes|no) | 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no |
(?(name)yes) | 同上,只是使用空表达式作为no |