正则表达式入门

162 阅读5分钟

测试工具:regex101.com/ deerchao.cn/tools/weges…

正则表达式30分钟入门教程:deerchao.cn/tutorials/r…

十分钟快速掌握正则表达式:www.bilibili.com/video/BV1da…

一、限定符

(1)? 表示前面的字符只出现1次或者0次

// 表示 `d` 这个字符可有可无, 匹配结果为 use 或 used
used?

(2)*:表示前面的字符可以出现0~多次

// 表示 a 和 c 之间可以出现 0~n 个 b
ab*c

(3)+:匹配出现1次以上的字符

ab+c

(4){}:指定出现的次数,或范围

// 希望 b 出现6次
ab{6}c
// 希望 b 出现 [2,6] 之间
ab{2,6}c
// 希望 b 出现的次数在2次以上
ab{2,}c

注意:以上运算符如果想针对多个字符,可以使用括号把多个字符括起来。这些被括起来的被称为子表达式或分组

(ab)+c
(ab){6}c

二、或运算

匹配的字符串:

a cat
a dog
a bird

(1)匹配 a cata dog,若都存在,则都匹配成功

// 注意 a 后面有空格,并且括号不能省略,否则匹配的将是 "a cat" 或者 "dog"
a (cat|dog)

(2)| 也可以用于分枝条件

正则表达式里的 分枝条件 指的是有几种规则,如果满足其中一种规则都应该当成匹配,具体方法是用 | 把不同的规则分隔开。

比如要匹配的邮编如下:

12345
12345-6789

可以使用 \d{5}-\d{4}|\d{5},这样上面的字符串都可以匹配成功,而如果改成 \d{5}|\d{5}-\d{4},那么只能匹配5位邮编,以及9位邮编的前5位。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分支的话,就不会去再管其他条件了。

三、字符类

匹配的字符串

abc
tiger
aabbcc
dog

(1)方括号:[]

[abc]+

方括号里的内容代表要求匹配的字符只能取自于它们。

另外,我们可以在方括号里指定字符的范围:

// 下面的正则表达式代表所有的大小写字母和数字0~9
[a-zA-Z0-9]+

(2)脱字符:^

如果在方括号的前面我们写一个尖号(脱字符),则代表要求匹配除了尖号后面列出的 [以外] 的字符。

比如 [^0-9] 代表所有的非数字字符(包括换行符)。

四、元字符

  • 数字字符:\d,相当于 [0-9]
  • 单词字符:\w,包括英文字符、数字及下划线
  • 空白符:\s,包含 Tab 和换行符
  • 非数字字符:\D
  • 非单词字符:\W
  • 非空白字符:\S
  • 任意字符,但不包含换行符:.(句点.)
  • \bword\b:\b 标注字符的边界(全字匹配)
  • \B:匹配不是单词开头或结束的位置
  • ^:匹配行首
// 只会匹配行首的 a
^a
  • $:匹配行尾
// 只会匹配行尾的 a
a$

五、贪婪和懒惰匹配

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以 a 开始,以 b 结束的字符串。如果用它来搜索 aabab的话,它会匹配整个字符串 aabab。这被称为贪婪匹配。

有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号 ?。这样 .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:

a.*?b 匹配最短的,以 a 开始,以 b 结束的字符串。如果把它应用于 aabab的话,它会匹配 aab(第一到第三个字符)和 ab(第四到第五个字符)。

匹配字符串

<span><b>This is a sample text</b></span>

上面说的 *+{} 在匹配字符串的时候,默认会匹配尽可能多的字符。即正则表达式默认使用贪婪匹配

比如

// 会匹配到:<span><b>This is a sample text</b></span>
<.+>

把贪婪匹配改为懒惰匹配,只需要在右边加一个 ? 就好了

// 会匹配到 <span><b></b></span>
<.+?>

六、注释

小括号的另一个用途是通过语法 (?#comment) 来包含注释。

例如:

25[0-5](?#250-255)|2[0-4]\d(?#200-249)|[01]?\d\d?(?#0-199)

七、处理选项

上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是 .Net 中常用的正则表达式选项:

名称说明
IgnoreCase(忽略大小写)匹配时不区分大小写。
Multiline(多行模式)更改^和的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,的精确含意是:匹配\n之前的位置以及字符串结束前的位置.)
Singleline(单行模式)更改.的含义,使它与每一个字符匹配(包括换行符\n)。
IgnorePatternWhitespace(忽略空白)忽略表达式中的非转义空白并启用由#标记的注释。
ExplicitCapture(显式捕获)仅捕获已被显式命名的组。

一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。事实上,为了避免混淆,在最新的 JavaScript 中,单行模式其实名叫 dotAll,意为点可以匹配所有字符,然而在指定该选项时,用的还是 Singleline 的首字母 s.

八、实例

1.RGB颜色值匹配

要求:匹配所有十六进制的 RGB 颜色值。

#00
#ffffff
#ffaaff
#00hh00
#aabbcc
#000000
#ffffffff

正则表达式

// \b 表示边界,避免最后一个不符合要求的字符串,也被识别成 RGB 颜色值
[a-fA-f0-9]{6}\b

2.IPv4 地址匹配

123
255.255.255.0
192.168.0.1
0.0.0.0
256.1.1.1
This is a string
123.123.0

正则表达式

// \b 表示边界
\b((25[0-5]|2[0-4]\d|[01]?\d\d?).){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)\b

\