JavaScript 正则入门
什么是正则?
JavaScript 内置对象,使用正则表达式(RegExp)可以进行强大的模式匹配、文本检索以及替换功能。
作用
- 验证指定数据格式是否符合要求
- 聊天表情
- 数据采集
- ...
创建正则表达式的方式
通过直接量的形式创建正则表达式:
var re = /d/g;
通过构造函数创建正则表达式:
var re = new RegExp('\d', 'g')
使用构造函数的方式创建正则表达式需要进行转义。
基础应用
最简单的正则表达式就是需要匹配的内容设置到正则当中去,例如:
var str = 'abc123hello456world';
// 假设需要使用的正则
var re = /hello/;
// 通过str中的match方法来实现匹配
console.log(str.match(re)); // ['hello']
在正则当中,大小写同样是敏感的,如果需要不区分大小写,则需要使用修饰符i。
例如:
var str = 'abc123HELLO456world'; // 字符串中的hello已经变为大写
// 设置需要使用的正则
var re = /hello/i; // 在正则的后面添加上需要使用的修饰符
// 直接进行匹配
str.match(re); // ['HELLO']
常用的修饰符:
- i 大小写不敏感
- g 全局匹配,查找所有匹配而非在第一个匹配后停止
- m 执行多行匹配
示例:
var str = 'abc123';
var re = /d/; // d 表示数字
str.match(re); // [1]
上面的代码中,正则表达式只匹配到了第一个数字就结束了,如果想要匹配全部的数字,可以使用g修饰符。
正则可以改写为如下:
var re = /d/g;
m 修饰符可以进行多行匹配,例如:
var str = 'abc
123
456';
var re = /^d+/gm;
str.match(re); // ['123', '456']
在上面的代码中,用到了^
这个符号,在正则中,这个符号表示正则的开始,$
表示正则的结束。
例如:
var str = '123abc
456';
var re = /^d/gm;
str.match(re);// ['1', '4']
上面代码中,正则匹配的是以数字开头的字符,并且全局匹配和多行匹配,在上面的字符串中,第一行是123abc,开头的数字是1,第二行是456,开头的数字是4.
量词
在正则中,想要表示匹配的数量,可以通过下面的两种形式:
-
通过特殊的符号表示数量次数
+
匹配一次到多次?
匹配零次到一次*
匹配0次到任意次
-
通过
{m,n}
来设置数量次数
首先,先来看下不使用量词和使用量词的区别。
示例:
var str = 'abc123cb231'; // 创建一个字符串,其中包括字母和数字
var re = /d/g; // 全局匹配数字
str.match(re); // [ "1", "2", "3", "2", "3", "1" ]
上面的示例中,d
匹配数字,g
是全局匹配,二者配合匹配到了字符串中的全部数字,但是所有的数字全被拆开了。
如果想要把数字整组的表示,就可以使用量词了。
示例:
var str = 'abc123cb231'; // 创建一个字符串,其中包括字母和数字
var re = /d+/g; // 全局匹配数字
str.match(re); // [ "123", "231" ]
使用{m,n}
的这种写法,可以设置最少和最多的匹配次数。
示例:
var str = 'abc123cb231'; // 创建一个字符串,其中包括字母和数字
var re = /d{1,2}/g; // 全局匹配数字 一次性最少匹配1次最多匹配2次
str.match(re); // [ "12", "3", "23", "1" ]
原子
在正则当中,一个字符即为一个原子。
示例:
var re = /a/; // 此时正则会匹配字符串中的字母a,此时可以说a 就是一个原子
在正则中,单独使用d
也是属于匹配一个原子。
示例:
var str = 'abc123';
var re = /d/;
str.match(re);//['1']
一个原子对应着一个字符串内容,上述的正则中如果想要匹配字符串中的所有数字,就可以使用三个d
,每一个d
代表一个数字字符。
示例:
var re = /ddd/;
当然,上述的写法很明显是不太理想的,可以通过量词来修饰原子,例如上面示例中字符串的数字一共有三位,就可以设置量词来进行修饰。
示例:
var re = /d{3}/;
选择修饰符
在正则中,可以通过选择修饰符|
来表示或者的关系。
示例:
var str1 = 'abc';
var str2 = 'adc';
var re = /abc|adc/;
str1.match(re); // ['abc']
str2.match(re); // ['adc']
上面的正则表达式中,通过|
选择修饰符表示了一个或者的关系,即匹配abc
或者匹配adc
。
除了使用|
来表示或者以外,还可以通过[]
来表示或者的关系。
示例:
var re1 = /a[bd]c/; // 表示匹配abc 或者adc
var re2 = /a[b,d]c/; // 表示匹配abc 或者a,c 或者 adc
需要注意的是,[]
除了表示或者,还可以表示一个范围。
示例:
var re = /a[0-9]/; // 表示匹配a0 - a9
如果在[]
的里面加入一个^
则表示除了的意思。
示例:
var re = /a[^bd]c/; // a和c之间匹配除了bd的其他内容
模式单元
在正则中,可以通过()
来表示模式单元,模式单元的作用如下:
- 改变优先级
- 将多个原子视为一个原子
- 将匹配的内容暂存在内存当中
- 可以通过`(?:原子)的形式来取消暂存内存
通过模式单元调整优先级非常类似于数学当中的操作。
示例:
var re = /abcd|efg/; // 匹配的内容是abcd 或者 efg
// 使用模式单元更改优先级
var re = /abc(d|e)fg/; // 匹配abcdfg 或者 abcefg
下面的示例中是通过模式单元将多个原子视为一个原子。
示例:
var re = /hello/; // 此时这个正则匹配的是hello
// 如果需要匹配1-3次的hello,就需要使用模式单元
var re = /(hello){1,3}/; // 此时通过模式单元将hello视为一个原子。
除了上述的两个功能以外,模式单元还有另外一个功能,就是将匹配的内容暂存到内存当中。
示例:
// 不使用模式单元进行匹配
console.log('aaa'.match(/aaa/));
// 使用模式单元将正则原子包裹
console.log('aaa'.match(/(a)(a)(a)/));
可以使用?:
不让模式单元将字符存在内存中。
示例:
console.log('aaa'.match(/(?:a)(?:a)(?:a)/));
字符类
在上面的很多案例中,都用到了d
,其实这个d
属于字符类,常用的字符类如下:
.
匹配除了 之外的所有字符d
匹配所有的数字D
匹配所有的非数字s
匹配所有空白字符包括 等S
匹配所有的可见字符w
匹配数字字母下划线W
匹配除了数字字母下划线其他字符匹配单词边界
B
匹配非单词边界
下面以单词边界为例。
示例:
var str = 'hello,world!How are you ?';
var re = /[a-zA-Z]+/g;
str.match(re); // [ "hello", "world", "How", "are", "you" ]
字符直接量
如果需要通过正则匹配一些特殊的字符,可以使用下面的内容。