正则表达式(一):理论基础部分

在 js 中,利用正则表达式进行验证是我们经常会遇到的功能需求, 今天就讲解一些正则表达式的理论基础;正则表达式是用来判断一段字符串是否匹配某一个规则, 通过正则表达式我们可以匹配到我们想要匹配的字符, 判断匹配字符是否存在, 一段字符串是否符合我们的匹配规则等等。

创建正则表达式的两种方式:

创建两种正则表达式有两种方法:
  1. let reg = new RegExp(pattern[, flags])
  2. let reg = /pattern/flags
上面两种方法创建正则除了包含有一个表达式 pattern 之外, 还包括一个可选的 flags 字段, 这个字段包含有几种字段:
  • g: 全局匹配正则表达式
  • i: 表示不区分大小写, 匹配的时候忽略大小写的匹配。
  • m: 表示多行匹配, 即到达某一行文本结束的时候还会继续查找下一行中是否包含有与模式匹配的值
通过上面两种方法创建的正则表达式返回的都是一个正则对象, 这个正则对象中包含有正则表达式中的一些方法例如: exec, match test 等方法。

元字符

正则表达式中的元字符是用来匹配一个位置或者字符集合中的一个字符, 元字符可以分为两种类型, 匹配位置的元字符和匹配字符的元字符;匹配位置的元字符:
元字符 含义
^ 匹配行的开始位置
$ 匹配行的结束位置
\b 可以用来匹配单词的开始或者结尾位置, 也就是单词的分界处
匹配字符的元字符:
元字符 含义
. 匹配除换行符之外的任意字符
\w 匹配单词字符(包括字母, 数字,下划线和汉字)
\W 匹配任意的非单词字符(和 \w) 相反
\s 匹配任意的空白字符, 比如空格符, 制表符或者换行符
\S 匹配任意的非空白符
\d 用于匹配任意的数字
\D 用于匹配任意的非数字字符

字符类

字符类是一个字符集合, 使用方括号 [] 定义, 表示匹配到方括号中的任意一个:注意: 除了 - 以及 ^ (只能用在开头, 表示否定) 这两个特殊字符之外, 其他的的特殊字符没有任何特殊的含义例如:
1
/<H[123456]>/
表示匹配 H1 H2 ... H6 中的任意一个标签在方括号中可以使用 - 用作连接符表示字符的范围:[0-9] 表示匹配 0 到 9 范围类的数字[a-z] 表示匹配 a 到 z 范围内的小写字母[a-zA-Z] 表示匹配 a到 z 或者 A 到 Z 范围内的英文字母在方括号中当 ^ 符号位于开头的时候, 表示对于当前字符集表示否定, 匹配的是排除在当前字符集中的字符:
1
/[^0-8]/.test(9); // true
要匹配上面的两个特殊符号, 那么需要我们使用反引号进行转义:
1
2
/[a\-c]/.test('-');
// true

限定符

使用字符类方括号 [] 或者 元字符只能表示匹配单个字符, 如果我们想要匹配多个字符的时候, 我们可以使用限定符进行范围的限定:限定符紧跟在单个字符后面,表示这个字符或者字符集重复的次数。 对于限定符有下面几种情况 :对于限定符也可分为贪婪匹配以及懒惰匹配, 下面的六种限定符为贪婪匹配, 懒惰匹配为在贪婪匹配后面添加 ? 表示懒惰匹配;
字符或者表达式 说明
{n} 重复 n 次
{n, } 表示至少重复 n 次
{n, m} 重复至少n 次, 至多 m 次
* 重复至少0次, 等同于 {0, }
+ 重复至少 1 次, 等同于 {1, }
? 重复 0 次 或者 1
例如:
1
2
3
4
5
const reg = /a.*b/;
"aabab".match(reg); // aabab

const reg = /a.{0,1}b/;
"aabab".match(reg); // aab
使用贪婪匹配与懒惰匹配的区别在于, 使用贪婪匹配会尽可能多的匹配字符, 使用懒惰匹配则是查找到满足匹配条件的字符串中字符较少的字符。例如:
1
2
3
4
5
6
7
8
const reg1 = /a.+b/;
const reg2 = /a.+?b/;
const str = "avbaab";

// 贪婪匹配
str.match(reg1); // avbaab
// 懒惰匹配
str.match(reg2); // avb

替换

在正则表达式中 | 用于表示当字符串匹配了 | 左边或者右边的规则的时候, 表示这个字符串匹配了当前的正则表达式,类似于 js 中的 || 操作符, 当 | 左边的正则不匹配, 那么进行右边的正则匹配。
1
let reg1 = \d{5} - \d{3} | d{5}; // 同时可以匹配 12345-678 或者 12345
注意: 使用 | 进行匹配的时候, 如果当左边的元素被匹配到的时候, 右边的元素将不会进行匹配。
1
2
3
4
5
> let str = 'goodbye';
> // | 两边不能有空格
> let regex = /goodbye|good/g;
> str.match(regex); // ['goodbye']
>

分组

使用 () 包裹起来的表达式在正则表达式中表示一个整体, 我们可以对这个整体进行限定符限制, 重复匹配例如:
1
2
// 匹配一个 ip 地址
let reg = /(\d{1,3}\.){3}/d{1,3}/;

总结

在正则中使用 [] 以及 | 都有 “或者” 的意思, 这两者可以根据不同的请求可以选择使用, 具体的对比如下:
描述符 优点 缺点
[] 适合单个字符之间的匹配, 需要转义的特殊字符比较少(^- 不能匹配多个字符结合的字符串,相对表达意思比较少, 只能表示匹配或者不匹配(使用^) 两种逻辑
竖直 可以匹配多个字符的字符串 当匹配正则中的特殊字符的时候需要进行转义