本文将对正则表达式做一个详细的介绍。
**正则表示是用于匹配字符串中字符组合的模式。**在JavaScript中,正则表达式也是对象【引用数据类型中RegExp类型】。这些模式被用于RegExp的exec和test方法,以及String中的match、matchAll、replace、search和split方法。
特点:
(1)灵活性、逻辑性和功能性非常强。
(2)可以迅速地用极简单的方式达到字符串的复杂控制。
创建正则表达式
方式一:通过调用RegExp对象的构造函数创建
javascript
let regexp = new RegExp(/123/);
console.log(regexp); // /123/
方式二:使用字面量创建正则表达式
javascript
let rg = /123/
测试正则表达式
test()方法,这是正则对象方法,用于检测字符串是否符合该规则,该对象会返回true或false,其参数是测试字符串。
javascript
let rg = /123/;
console.log(rg.test(123));//匹配字符中是否出现123 出现结果为true
console.log(rg.test('abc'));//匹配字符中是否出现123 未出现结果为false
正则表达式中的特殊字符
正则表达式修饰符
- /i :执行对大小写不敏感的匹配。
- /g :执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
- /m :执行多行匹配
正则表达式模式
- [abc] :查找括号之间的任何字符。
- [^abc] :查找任何不在方括号之间的字符。
- [0-9] :查找任何从 0 至 9 的数字。
- [^0-9] :查找任何不在括号内的字符(任何非数字)。
- (x|y) :查找任何指定的选项。
javascript
let rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
console.log("---------------------------------------------------------------")
let rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//false
console.log("---------------------------------------------------------------")
// - 短横线 表示一个范围
let reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
console.log("----------------------------------------------------------------")
// 字符组合
let reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
let reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true
元字符
元字符是具有特殊含义的字符:
- . :这里的.(点)表示查找单个字符,除了换行符或行终止符。
- \w :查找单词字符。【类似但不等价于"[A-Za-z0-9_]",这里的"单词"字符使用Unicode字符集。】
- \W:查找非单词字符。【匹配任何非单词字符。等价于"[^A-Za-z0-9_]"。】
- \d :查找数字。
- \D:查找非数字字符。
- \s :查找空白字符。
- \S:查找非空白字符。
- \b :在单词的开头/结尾查找匹配项,开头如下:\bHI,结尾如下:HI\b。
- \B :查找匹配项,但不在单词的开头/结尾处。
- \0 :查找NULL字符。
- \n :查找换行符。
- \f :查找换页符。
- \r :查找回车符。
- \t :查找制表符。
- \v:查找垂直制表符。
- \xxx:查找以八进制数 xxx 规定的字符。
- \xdd:查找以十六进制数 dd 规定的字符。
- \uxxxx:查找十六进制数 xxxx 规定的 Unicode 字符。
量词
- n+:匹配至少包含一个n的字符串。
- n*:匹配包含零个或多个n的字符串。
- n?:匹配包含零个或一个n的字符串。
- n{X}:匹配包含X个n的序列的字符串。
- n{X, Y}:匹配包含X至Y个n的序列的字符串。
- n{X,}:匹配包含至少X个n的序列的字符串。
- n$:匹配以n结尾的字符串。
- ^n:匹配以n开头的字符串。
- ?=n:匹配其后紧接指定字符串n的字符串。
- ?!n:匹配其后没有紧接指定字符串n的字符串。
括号匹配区分
- 大括号------量词符。里面表示重复次数。
- 中括号------字符集合。匹配方括号中的任意字符。
- 小括号------表示优先级。
核心匹配
- * :重复0次或多次
- +:重复1次或多次
- ?:重复0次或1次
- {n}:重复n次
- {n,}:重复n次或更多次
- {n,m}:重复n到m次
javascript
// 量词符:用来设定某个模式出现的次数
// 简单理解:就是让下面的a这个字符重复多少次
var reg = /^a$/; //以a开头
// * :相当于 >=0 可以出现0次或者很多次
var reg = /^a*$/; //以a开头,匹配0个或多个a
console.log(reg.test('')); //true 0个a
console.log(reg.test('a'));//true 一个a
console.log(reg.test('aaaa')); //true 多个a
console.log("---------------------------------------------")
// + :相当于 >=1 可以出现1次或者很多次
var reg = /^a+$/; //以a开头,匹配至少1个a
console.log(reg.test(''));//false 0个a
console.log(reg.test('a'));//true 1个a
console.log(reg.test('aaaa'));//true 多个a
console.log("---------------------------------------------")
// ? :相当于 1 || 0 重复1次或者0次
var reg = /^a?$/; //以a开头,匹配0个或1个a
console.log(reg.test('')); //true 0个a
console.log(reg.test('a'));//true 1个a
console.log(reg.test('aaaa'));//false 多个a
console.log("---------------------------------------------")
// {3} :就是重复3次
var reg = /^a{3}$/; //以a开头,匹配3个a
console.log(reg.test(''));//false 0个a
console.log(reg.test('a'));//false 1个a
console.log(reg.test('aaaa'));//false 多个a
console.log(reg.test('aaa'));//true 3个a
console.log("---------------------------------------------")
// {3,}: 大于等于3 >=3
var reg = /^a{3,}$/; //以a开头,匹配3个a或3个以上的a
console.log(reg.test(''));//false 0个a
console.log(reg.test('a'));//false 1个a
console.log(reg.test('aaaa'));//true 多个a
console.log(reg.test('aaa'));//true 3个a
console.log("---------------------------------------------")
// {3,16}: 等于3 并且 小于等于16
var reg = /^a{3,16}$/; //以a开头,匹配3-16个a
console.log(reg.test(''));//false 0个a
console.log(reg.test('a'));//false 1个a
console.log(reg.test('aaa'));//true 3个a
console.log(reg.test('aaaa'));//true 4个a
console.log(reg.test('aaaaaaaaaaaaaaaa'));//true 16个a
console.log(reg.test('aaaaaaaaaaaaaaaaa'));//false 17个a
边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符:
- ^:表示匹配行首的文本(以谁开始)
- $:表示匹配行尾的文本(以谁结束)
PS:如果^和$在一起匹配,则表示必须是精确匹配。
javascript
var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc')); // true
console.log(rg.test('abcd')); // true
console.log(rg.test('aabcd')); // true
console.log('---------------------------');
var reg = /^abc/; // 必须以abc开头
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false
正则修复边界
javascript
// 使用 正则表达式边界修复错误字符串
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;
// 1) 使用 ^ 修正字符串开始处和换行后的匹配。
buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
console.log(1, buggyMultiline); // 修复 'tey'=>'hey'(字符串开始) , 'tangs'=>'hangs'(换行后)
// 1 'hey, ihe light-greon apple\nhangs on ihe greon traa' //把每行开头的 t 换成了 h
// 2) 使用 $ 修正字符串结尾处的匹配。
buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
console.log(2, buggyMultiline); // 修复 'traa' => 'tree'.
// 2 'hey, ihe light-greon apple\nhangs on ihe greon tree.' //把每行结尾的aa换成ee.
// 3) 使用 \b 修正单词和空格边界上的字符。
buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
console.log(3, buggyMultiline); // 修复 'ihe' => 'the' 不影响 'light'.
// 3 'hey, the light-greon apple\nhangs on the greon tree.' //\b空格后的第一个字符i,替换成t
// 4) 使用 \B 匹配实体边界内的字符。
fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
console.log(4, fixedMultiline); // 修复 'greon' 不影响'on'.
// 4 'hey, the light-green apple\nhangs on the green tree.' //\B不在空格后的o,即英文单词中的o替换成e
正则表达式前瞻后顾、负前瞻和负后顾
前瞻(先行断言)
- (x|y):查找指定的选项。
- ?=n:匹配其后紧接指定字符串n的字符串
- x(?=y):匹配x,只有当x后面跟着y,这叫做先行断言。例如:
- /Jack(?=Sprat)/ 会匹配到'Jack'仅当它后面跟着'Sprat'。
- /Jack(?=Sprat|Frost)/ 匹配'Jack'仅当它后面跟着'Sprat'或者是'Frost'。
- 但是'Sprat'和'Frost'都不是匹配结果的一部分。
首先使用括号()来提升优先级,然后使用?=,对后面紧跟e的h,进行全局搜索:
javascript
var str= 'hello hi world';
// 前瞻 查找 e 前面的h
var pe = /h(?=e)/g;
var newStr = str.replace(pe,'T');
console.log(newStr); //Tello hi world
上述代码中,可以看到,使用正则表达式匹配出,h后面紧跟e的字符h,可以看到只有一个,把符合的h替换成T。
后顾(后行断言)
- (x|y):查找指定的选项。
- (?<=y)x:匹配x,只有当x前面是y,这叫做后行断言 。例如:
- /(?<=Jack)Sprat/ 会匹配到' Sprat '仅仅当它前面是' Jack '。
- /(?<=Jack|Tom)Sprat/ 匹配'Sprat '仅仅当它前面是'Jack'或者是'Tom'。
- 但是'Jack'和'Tom'都不是匹配结果的一部分。
首先使用括号()来提升优先级,然后使用?<=,堆前面紧跟 l 的 d 进行全局搜索:
javascript
// 后顾 查找l后面的 d
var str= 'hello hi world';
var pe = /(?<=l)d/g;
var newStr = str.replace(pe,'M');
console.log(newStr); //hello hi worlM
上述代码中,通过正则表达式匹配d,d前面紧跟 l ,符号的只有最后一个d,把d替换成M。
负前瞻(先行否定断言)
- (x|y):查找指定的选项。
- x(?!y):当x后面不跟着y时,匹配x,这被称为正向否定查找。例如:
- /\d+(?!\.)/ 匹配一个数字。仅仅当这个数字后面没有跟小数点的时候。
- 正则表达式 /\d+(?!\.)/.exec("3.141") 匹配'141'而不是'3.141'
首先使用括号()来提升优先级,然后使用?!,对后面不是紧跟e的h进行全局搜索:
javascript
// 负前瞻 查找h后面不是e的
var str= 'hello hi world';
var pe = /h(?!e)/g;
var newStr = str.replace(pe,'N');
console.log(newStr); //hello Ni world
上述代码中,通过正则表达式匹配h,h后面不是e的h,这里符合的只有hi,这里把h替换为N。
负后顾(后行否定断言)
- (x|y):查找指定的选项。
- (?<!y)x:当x前面不是y时,匹配x,这被称为反向否定查找。例如:
- /(?<!-)\d+/.exec('3') 匹配到"3"。
- /(?<!-)\d+/.exec('-3') 因为这个数字前有负号,所以没匹配到。
首先使用括号()来提升优先级,然后使用?<!,对前面不是紧跟e的 l 进行全局搜索:
javascript
// 负后顾 查找l前面不是e的
var str= 'hello hi world';
var pe = /(?<!e)l/g;
var newStr = str.replace(pe,'Q');
console.log(newStr); //helQo hi worQd
上述代码中,匹配l,且l前面不是e,这里符合的有两个,第一个是o前面的 l 替换为Q,第二个是d前面的 l ,替换为Q。
RegExp 对象属性
- constructor:返回创建RegExp对象原型的函数。
- global:检测是否设置了"g"修饰符。
- ignoreCase:检查是否设置了"i"修饰符。
- lastIndex:规定开始下一个匹配的索引。
- multiline:检查是否设置了"m"修饰符。
- source:返回RegExp模式的文本。
具体示例,可以参考Mdn官网:RegExp介绍
RegExp对象方法
- compile():在1.5版本中已弃用。编译正则表达式。
- exec():测试字符串中的匹配项。返回第一个匹配项。
- test():测试字符串中的匹配项。返回true或false。
- toString():返回正则表达式的字符串值。
支持正则表达式的String对象的方法
|---------|-----------------|-------------|-------------------------|
| 方法 | 描述 | Firefox(FF) | Internet Explorer(IE) |
| search | 检测与正则表达式匹配的值 | 1 | 4 |
| match | 找到一个或多个正则表达式的匹配 | 1 | 4 |
| replace | 替换与正则表达式匹配的子串 | 1 | 4 |
| split | 把字符串分割为字符串数组 | 1 | 4 |
案例
1、验证座机号码
javascript
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;
console.log(reg.test('010-12345678'));// true
2、手机号验证
javascript
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
let reg = /^1[3|4|5|7|8][0-9]{9}$/
console.log(reg.test('13860068008')) //true
3、验证qq号
javascript
//QQ号验证: /^[1-9]\d{4,}$/;
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
let reg = /^[1-9]\d{4,}$/;
console.log(reg.test(2002008000)) //true
4、正则替换replace
javascript
var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
console.log('---------------------------');
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
console.log('---------------------------');
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
console.log('---------------------------');
//全部替换g
var nStr = str.replace(/a/g,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"
5、正则替换敏感词
html
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
var text = document.querySelector('textarea');
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
div.innerHTML = text.value.replace(/激情|gay/g, '**');
}
</script>
正则特殊字符大全(MDN)
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
区分不同类型的字符,例如区分字母和数字。
表示表达式字符的分组和范围。
表示匹配的字符或表达式的数量。
基于 unicode 字符属性区分字符。例如大写和小写字母、数学符号和标点。
正则表达式的特殊字符,参考链接:正则表达式
如果大家不理解的正则表达式,可以使用正则表达式可视化工具,这里推荐一个英文简约版:
Regex for playground - IHateRegex
以及中文版:正则表达式解析器 | 代码生成器