# 正则表达式笔记
# 一、介绍
正则表达式就是记录文本规则的代码。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。比如找出一段文本中所有的数字。
如果你想查找某个目录下的所有的 Word
文档的话,你会搜索 *.docx
。在这里,*
会被解释成任意的字符串。
和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂。
# 二、元字符
hi
匹配含有 hi
的字符串,包括 him
,history
。
\bhi\b
精确查找,只匹配 hi
。
\b
是一个元字符,代表单词的开始和结束,它匹配一个位置。
\d
匹配数字。
0\d\d-\d\d\d\d\d\d\d\d
这个式子可以化简为
0\d{2}-\d{8}
第一个表示数字重复两次,第二个表示重复八次。
\D [^\d]
匹配非数字字符。
.
匹配任意字符
\w
匹配字母数字下划线
\ba\w*\b
首先匹配 a
开头,\w
匹配字母数字下划线或汉字,*
表示 *
之前的可以任意使用任意次(可以是0次)。
\d+
匹配任意个数字 +
表示匹配 1 次或任意次,注意至少要 1 次。
\b\w{6}\b
匹配 6 个字符的字符串。
\d{4,10}
匹配 4 到 10 个字符的字符串,包括 4 和 10。
# 三、字符转义
如果你想查找元字符本身,比如 *
,-
,那么你可以用一个
反斜杠+查找的元字符,如果想查找 \
,那么就是 \\
。
# 四、重复
# 五、字符类
如果想要匹配没有预定义元字符的字符集合,比如 1 3 5,或者 aeiou
,那么应该怎么办呢?
[aeiou] [135]
使用中括号[]
进行匹配。
试一下更复杂的表达式
\(?0\d{2}[) -]?\d{8}
拆除一部分一部分分析。
\(?0\d{2}
表示 (
出现 1 次或 0 次,然后是一个 0,再加 2 个数字,
[) -]?
再加上右括号 空格 减号中的1个,这个出现的次数是 1 次或 0 次,
\d{8}
最后再加上 8 个数字。 可以匹配
(012)12345678
012)12345678
(012 12345678
(012-12345678
01212345678
2
3
4
5
# 六、分枝条件
有时候我们需要多种条件,比如有三位区号,但是我也要四位区号。类似 if ,else if。
分支条件指的是有几种规则,只要满足任意一个规则,那么就可以匹配。
\(0\d{3}\)[- ]?\d{8}|0\d{3}[- ]?\d{8}
|
将两个表达式隔开,一个一个分析。
有括号的以 0 开头四位区号,第二个没括号。
匹配分支时,从左到右,左边满足就不会管右边。
# 七、分组
我们已经学过数字和字符的重复,比如 \d{3}
, 3 个数字,那么我们也可以对表达式进行重复。
通过小括号来指定子表达式,然后可以指定子表达式的重复次数。
(\d{1,3}\.){3}\d{1,3}
简单 ip 地址匹配表达式,\d{1,3}
匹配 1 到 3 位数字,\.匹配符号 . ,被小括号包括,说明是个分组,后面的{3}表示分组重复的次数。
不过这个表达式不够严谨,会匹配到不存在的 ip 地址。 比如666.666.666.666。
正确的匹配 ip 表达式
((2[0-4]\d|25[1-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[1-5]|[01]?\d\d?)
依然一个一个看,ip 地址的数字范围是[0, 255]。 可划分为:
- [0,9]
- [10,99]
- [100,199]
- [200,249]
- [250,255]
[01]?\d\d?
匹配 [0, 199]
2[0-4]\d
匹配 [200, 249]
25[1-5]
匹配 [250,255]
# 反义
# 后向引用
后向引用用于重复搜索
(\d)\d\1
第一个\d
是一个匹配数字捕获分组,第二个普通的匹配数字
,\1是匹配捕获分组中的字符。
结果就是匹配类似 303 575这种字符串。
\b(\w+)\b\s+\1\b
(\w+)是一个分组,匹配一个单词,\1表示的前面出现过的分组1的内容。\s+匹配一个或多个空格。
也可以自己给分组起个名称。
(?
\w+)
那么first就是分组的名称了,反向引用就是
\k
# 零宽断言
零宽断言用于指定一个位置, 用于查找在某些内容(但并不包括这些内容)之前或之后的东西.
\w+(?=ing)
匹配以ing结尾的前面部分(不包括ing)。
(?<=sin)\w+
匹配sin开头的单词的后半部分,不包括 sin。