正则表达式就是记录文本规则的代码。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。比如找出一段文本中所有的数字。
如果你想查找某个目录下的所有的 PPT
的话,你会搜索 *.pptx
。在这里,*
会被解释成任意的字符串。
和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂。
hi
匹配含有 hi
的字符串,包括 him
,high
,history
。
\bhi\b
精确查找,只匹配 hi
。
\b
是一个元字符,代表单词的开始和结束,它匹配一个位置。
0\d\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
有时候我们需要多种条件,比如有三位区号,但是我也要四位区号。类似 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
。