1.正则表达式(RegExp):对字符串进行逻辑匹配运算 内置对象
- 正则是对象类型:
- 表达式作用:对字符串进行匹配运算
- 作用与场景:表单验证(手机号,验证码,账号,邮箱等)
2.如何使用: 2个流程
1.创建正则对象: let reg = new.RegExp(‘正则表达式’)
2.调用正则对象test()方法: reg.test(‘要检测的字符串’)
-
(1) 创建一个正则对象: 检测字符串中有没有a
let reg = new RegExp(/a/)
-
(2)调用正则对象的test()方法 ------- //true : 符合规则 // false : 不符合规则
console.log(reg.test(‘123456’))//false
console.log(reg.test(‘abc456’))//true
3.字符类[ ] [^ ]
-
1 /abc/ : 原义文本字符。 字符串本身含义,有没有abc
-
2 /[abc]/ : 字符类。 把a 和 b 和 d 归为一类,只要符合任何一类特征就可以。
说人话: 有a 或 有b 或 有c,任何一个 就符合要求 -
3./[^abc]/ : 反向字符类。 把不是a 和 不是b 和 不是c归为一类。
说人话: 有不是a 或 不是b 或 不是c,任何一个就符合要求
// [abc] 检测有没有 是 a b c任何一个字符(只要有是 a b c的任意字符)
console.log( /[abc]/.test('a123'))//true
console.log( /[abc]/.test('a1b2c3'))//true
console.log( /[abc]/.test('abc123'))//true
console.log( /[abc]/.test('abcaaabbbccc'))//true
// /[^abc]/ : 检测有没有 不是 a b c任何一个的字符 (只要有不是a b c的任意字符)
console.log( /[^abc]/.test('a123'))//true
console.log( /[^abc]/.test('a1b2c3'))//true
console.log( /[^abc]/.test('abc123'))//true
console.log( /[^abc]/.test('abcaaabbbccc'))//false
4.范围类/[0-9]/ /[a-z]/ /[A-Z]/
- /[0-9]/ : 检测有没有数字
- /[a-z]/ : 检测有没有小写
- /[A-Z]/ : 检测有没有大写
1.范围类可以连写
- /[0-9a-zA-Z]/ : 检测有没有数字 或 字母
2.范围类是一个闭区间
- /[5-8]/ : 包含5,也包含8
3.范围类 左边一定要小于右边
- /[5-8]/ : 正确
- /[8-5]/ : 报错
console.log( /[0-9]/.test('abcABC'))//false
console.log( /[0-9]/.test('abc123ABC'))//true
console.log( /[a-z]/.test('abcABC'))//true
console.log( /[a-z]/.test('abc123ABC'))//true
console.log( /[A-Z]/.test('abcABC'))//true
console.log( /[A-Z]/.test('abc123ABC'))//true
console.log( /[0-9a-zA-Z]/.test('abcABC'))//true
console.log( /[0-9a-zA-Z]/.test('abc123ABC'))//true
5.预定义类 \d \D \s \S \ w \W
/*预定义类: 正则表达式提供好的用来匹配常见的字符类
预定义类 等价类 含义
. [^\r\n] 除了回车和换行之外的所有字符
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\s [\f\n\r\t\v] 空白字符
\S [^\f\n\r\t\v] 非空白字符
\w [a-zA-Z_0-9] 单词字符(字母、下划线、数字)
\W [^a-zA-Z_0-9] 非单词字符
//1. /./ : 检测除回车换行之外的任意字符。
//只有一种情况会得到false, 字符串全部都是回车或换行
console.log( /./.test('\n\r'))//false
//2. \d : digit 相当于[0-9],检测数字字符
//3. \D : non digit 相当于[^0-9],检测非数字字符
//4. \s : space 检测字符串有没有空格字符 [\f\n\r\t\v]
console.log( /\s/.test('我爱你 一万年'))//true
console.log( /\s/.test('我爱你一万年'))//false
//5. \S : non space:检测字符串有没有非空格字符
//6. \w : word 单词字符 : 字母、数字、下划线_
console.log( /\w/.test('_____') )//true
//7. \W : non word 非单词字符
console.log( /\W/.test('zxk123456'))//false
console.log( /\W/.test('zxk123456=='))//true
6.(重点)边界:/^/ ---- / $/
重点:严格匹配 : 开头边界与结尾边界同时存在
1.开头边界
/^abc/
正确含义: 开头a + bc
错误含义: 以abc开头
console.log( /^abc/.test('123abcabc') )//false
console.log( /^abc/.test('a1b2c3') )//false
console.log( /^abc/.test('abcabc') )//true
2.结尾边界
/abc$/
正确含义:ab + c结尾
错误含义: 以abc结尾
console.log( /abc$/.test('123abcabc') )//true
console.log( /abc$/.test('a1b2c3') )//false
console.log( /abc$/.test('abcabc') )//true
3.严格匹配:开头边界 + 结尾边界 同时使用
/* 3.严格匹配 : 开头边界 + 结尾边界 同时使用
/^abc$/
正确含义: 以a开头 + b + c结尾
错误含义: 以abc开头,以abc结尾
总结: 不是说开头有abc,结尾有abc。 而是指这个abc既要在开头,也要在结尾。唯一答案:abc本身
*/
console.log( /^abc$/.test('123abcabc') )//false
console.log( /^abc$/.test('a1b2c3') )//false
console.log( /^abc$/.test('abcabc') )//false
// /^abc$/ ; 全世界只有唯一的一个正确答案 abc
console.log( /^abc$/.test('abc') )//true
// /^a$/ : 正确含义: a既需要开头位置,也要在结尾位置 错误:开头是a,结尾是a
console.log( /^a$/.test('aa') )//false
console.log( /^a$/.test('a') )//true
7.量词 ? + * {n} {n,m} {n,}
/*量词: 表示字符出现的数量
量词 含义
? 出现零次或一次(最多出现一次)
+ 出现一次或多次(至少出现一次)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n-m次
{n,} 出现至少n次(>=n)
// ? 和 + 和 * 区别
// ? 最多只能匹配1个 <= 1
console.log('123456789abc'.replace(/\d?/, 'X'))//X23456789abc
// + 可以匹配多个 >= 1
console.log('123456789abc'.replace(/\d+/, 'X'))//Xabc
// * 可以匹配多个 无次数限制
console.log('123456789abc'.replace(/\d*/, 'X'))//Xabc
// + 和 * 区别
// + 匹配要求 >=1 一定要先从数字位置开始找
console.log('a123456789abc'.replace(/\d+/, 'X'))//aXabc
// * 可以匹配0次, a的位置有0次数字,把没有数字的位置替换成X (找到0次了,下班了)
console.log('a123456789abc'.replace(/\d*/, 'X'))//Xa123456789abc
// /\d{6}/ : 只能匹配6个数字
console.log('a123456789abc'.replace(/\d{6}/, 'X'))//aX789abc
// /\d{6,8}/ : 匹配6-8, 就多不就少
console.log('a123456789abc'.replace(/\d{6,8}/, 'X'))//aX9abc
// /\d{6,}/ : 匹配>=6, 就多不就少
console.log('a123456789abc'.replace(/\d{6,}/, 'X'))//aXabc
8.分组()
() : 正则中有三种用法
1. () : 分组。 用于量词,让量词对多个字符生效
/love{3}/ : 默认量词只能对一个字符生效 love + eee
/(love){3}/ : (love) 出现3次
2. () : 提升优先级。 通常与 | 一起用
需求: 匹配 love 或 live
/lo|ive/ : |对两边所有的字符生效。 lo 或 ive
/l(o|i)ve/ : l + o或i + ve
3.反向引用 :
(1)默认情况下,正则表达式提取()中匹配到的结果,存入RegExp对象的$1-$9的属性中
(2)提取到小括号中的内容之后,就可以使用$1-$9进行反向引用
//1. () : 分组。 用于量词,让量词对多个字符生效
console.log( /love{3}/.test('lovelovelove'))//false
console.log( /love{3}/.test('loveeee'))//true
console.log( /(love){3}/.test('lovelovelove'))//true
console.log( /(love){3}/.test('loveeee'))//false
//2. () : 提升优先级。 通常与 | 一起用
console.log( /lo|ive/.test('lo123'))//true
console.log( /lo|ive/.test('123ive'))//true
console.log( /lo|ive/.test('love'))//true
console.log( /l(o|i)ve/.test('lo123'))//false
console.log( /l(o|i)ve/.test('123ive'))//false
console.log( /l(o|i)ve/.test('love'))//true
//3.反向引用 :
//(1)默认情况下,正则表达式提取()中匹配到的结果,存入RegExp对象的$1-$9的属性中
//(2)提取到小括号中的内容之后,就可以使用$1-$9进行反向引用
//反向引用实际场景:格式转换
//例如:大陆生产日期格式 yyyy-mm-dd 香港日期: dd/mm/yyyy
console.log( '2021-12-20'.replace(/(\d{4})-(\d{2})-(\d{2})/,'$3/$2/$1') )//20/12/21
9.修饰符 g i
1.修饰符作用 : 修饰正则运算结果
2.修饰符语法 : /正则/修饰符
g : global 全局匹配
i : intensity 不区分大小写
// g : global 全局匹配
//1. /a/ : 默认情况下,正则表达式只能匹配满足条件第一个字符
console.log( '123aaa456AAA'.replace(/a/,'X') )//123Xaa456AAA
//2. /a/g : 匹配所有a
console.log( '123aaa456AAA'.replace(/a/g,'X') )//123XXX456AAA
//i : intensity 不区分大小写
//1. /a/ :只能匹配小写a 默认正则区分大小写。
console.log( 'A123aaa456AAA'.replace(/a/,'X') )//A123Xaa456AAA
//2. /a/i : 匹配a,不区分大小写
console.log( 'A123aaa456AAA'.replace(/a/i,'X') )//X123aaa456AAA
//替换所有的a和A : 修饰符可以连写
// /a/ig : 全局匹配 且 不区分大小写
console.log( 'A123aaa456AAA'.replace(/a/ig,'X') )//X123XXX456XXX
10.简易正则判断验证
封装部分
<script>
/* 思路分析
1.点击发送验证码: 5秒倒计时
2.输入框失去焦点,正则验证
用户名: /^\w{6,20}$/
手机号 : /^(13\d|14\d|15\d|16[2567]|17\d|18\d|19\d)\d{8}$/
验证码 : /^\d{6}$/
密码 : /^\w{6,20}$/
如果正则不通过,则显示这个输入框下一个span标签。 通过则隐藏
3.点击协议: 切换类样式
4.点击下一步
0.表单中的按钮需要阻止默认跳转
1.检查协议是否勾选
2.非空判断: 检查有没有 空的表单 (开关法)
3.正则判断: 检查是不是所有正则都通过 (开关法)
4.注册成功:跳转登录页
*/
// 1.点击发送验证码: 5秒倒计时
let code = document.querySelector('.code')
code.onclick = function(){
//(1)声明一个倒计时变量
let num = 5
//(2)开启间隔1秒定时器
let timeID = setInterval(function(){
code.innerText = `0${num--}秒后重新获取`
if( num < 0){
//结束倒计时
code.innerText = '获取验证码'
clearInterval(timeID)
}
},1000)
}
/*
2.输入框失去焦点,正则验证
用户名: /^\w{6,20}$/
手机号 : /^(13\d|14\d|15\d|16[2567]|17\d|18\d|19\d)\d{8}$/
验证码 : /^\d{6}$/
密码 : /^\w{6,20}$/
如果正则不通过,则显示这个输入框下一个span标签。 通过则隐藏
*/
//正则校验封装 reg:正则 ele:需要做正则判断的元素
function checkInput(reg,ele){
//(1)先检查用户有没有输入,如果没有输入就不需要正则匹配
if( ele.value.trim() == '' ){
ele.nextElementSibling.style.display = 'none'
return
}
//(2)用户有输入,才做正则验证
if( reg.test(ele.value) ){//true通过
//隐藏下一个元素
ele.nextElementSibling.style.display = 'none'
}else{
//显示下一个元素
ele.nextElementSibling.style.display = 'block'
}
}
let username = document.querySelector('[name="username"]')
let phone = document.querySelector('[name="phone"]')
let codeInput = document.querySelector('[name="code"]')
let password = document.querySelector('[name="password"]')
let confirm = document.querySelector('[name="confirm"]')
//2.1 用户名
username.onblur = function(){
checkInput(/^\w{6,20}$/,this)
}
//2.2 手机号
phone.onblur = function(){
checkInput(/^(13\d|14\d|15\d|16[2567]|17\d|18\d|19\d)\d{8}$/,this)
}
//2.3 验证码
codeInput.onblur = function(){
checkInput(/^\d{6}$/,this)
}
//2.4 密码
password.onblur = function(){
checkInput(/^\w{6,20}$/,this)
}
//2.5 确认密码
confirm.onblur = function(){
//检查confirm与password内容是否一样
if( confirm.value === password.value ){
this.nextElementSibling.style.display = 'none'
}else{
this.nextElementSibling.style.display = 'block'
}
}
//3.点击协议: 切换类样式
let queren = document.querySelector('.icon-queren')
queren.onclick = function(){
//切换类
/*
新增: classList.add('类名')
移除:classList.remove('类名')
切换:classList.toggle('类名')
包含:classList.contains('类名')
*/
this.classList.toggle('icon-queren2')
}
//4.点击下一步
/*
0.表单中的按钮需要阻止默认跳转
1.检查协议是否勾选
2.非空判断: 检查有没有 空的表单 (开关法)
3.正则判断: 检查是不是所有正则都通过 (开关法)
4.注册成功:跳转登录页
*/
document.querySelector('.submit').onclick = function(e){
//0.表单中的按钮需要阻止默认跳转
e.preventDefault()
//1.检查协议是否勾选 : 没有则弹窗提示
if( !queren.classList.contains('icon-queren2') ){
alert('请先勾选协议')
return
}
//2.非空判断: 检查有没有 空的表单
//获取所有表单元素
let inputList = document.querySelectorAll('form input')
//(1)声明开关 默认值true:全部填写
let isAllOk = true
//(2)检查所有的列表有没有 未填写的
for(let i = 0;i<inputList.length;i++){
if( inputList[i].value.trim() == '' ){
isAllOk = false
break
}
}
//(3)根据开关实现需求
if( !isAllOk ){
alert('表单不能为空')
return
}
//3.正则判断: 检查有没有 未通过正则
//获取所有span
let msgList = document.querySelectorAll('form .msg')
//(1)声明开关 默认值true:全部通过
let isAllPass = true
//(2)检查所有的列表有没有 未通过的
for(let i = 0;i<msgList.length;i++){
if( msgList[i].style.display == 'block' ){
isAllPass = false
break
}
}
//(3)根据开关实现需求
if( !isAllPass ){
alert('格式错误')
return
}
//4.注册成功
location.href = './login.html'
}
</script>
11.开关思想:
-
开关思想 : 用于解决一类问题的思路
-
判断数组中是否所有元素都满足条件
1.选择框是否全部勾选
2.表单是否全部填写
3.正则是否全部通过