正则表达式入门教程

介绍

正则表达式就是记录文本规则的代码。

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。比如找出一段文本中所有的数字。

如果你想查找某个目录下的所有的 PPT 的话,你会搜索 *.pptx 。在这里,* 会被解释成任意的字符串。

和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂。

元字符

hi

匹配含有 hi 的字符串,包括 himhighhistory

\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}

匹配 410 个字符串,包括 410

字符转义

如果你想查找元字符本身,比如 *- ,那么你可以用一个 反斜杠 + 查找的元字符,如果想查找 \ ,那么就是 \\

重复

字符类

如果想要匹配没有预定义元字符的字符集合,比如 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