正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象,通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。
JavaScript中的使用场景
表单验证(匹配)
过滤敏感词(替换)
字符串中提取我们想要的部分(提取)
正则表达式语法分两步,一是定义规则,二是看是否匹配。
查找匹配字符串
test()
方法 用于判断是否有符合规则的字符串,返回的是布尔值 找到返回true
,否则false
exe()
方法用于检索(查找)符合规则的字符串,找到返回数组,否则为null
// 正则表达式使用
const str = '我是来自河南洛阳,我叫霍欣标'
// 1. 定义规则
const reg = /霍欣标/
// 2. 是否匹配? test()用来查看正则表达式与指定的字符串是否匹配
console.log(reg.test(str)) // true 或 false
// 3. 检索(查找)符合规则的字符串 exec()
console.log(reg.exec(str)) // 返回数组 或 null(未知)
元字符
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。
而元字符是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
例如:26个英文字符,普通字符abcdefghijklm…
换成元字符为[a-z]
元字符分类
边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
量词(表示重复次数)
字符类(\d
表示0~9
)
边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
^
表示匹配行首的文本(以谁开始),$
表示匹配行尾的文本(以谁结束)。^
和$
在一起,表示必须是精确匹配。
console.log(/哈/.test('哈')) // true
console.log(/哈/.test('哈哈')) // true
console.log(/哈/.test('二哈')) // true
// 边界符
// 1. 以哈开头
console.log(/^哈/.test('哈')) // true
console.log(/^哈/.test('二哈')) //false
// 2. 以哈开头
console.log(/^哈$/.test('哈')) // true
// 精确匹配,以哈结尾,只能有一个哈
console.log(/^哈$/.test('哈哈')) //false
量词
量词用来设定某个模式出现的次数。注意:逗号左右两侧千万不要出现空格
*
重复零次或更多次+
重复一次或更多次?
重复零次或一次{n}
重复n次{n,}
重复n次或更多次{n,m}
重复n到m次
// 量词 * 类似 >= 0次
console.log(/^哈$/.test('哈')) // true
console.log(/^哈*$/.test('哈')) // true
console.log(/^哈*$/.test('哈哈')) // true
console.log(/^哈*$/.test('哈很啥')) // false
console.log(/^哈*$/.test('哈很傻')) // false
// 量词 + 类似 >= 1次
console.log(/^哈$/.test('哈')) // true
console.log(/^哈+$/.test('')) // false
console.log(/^哈+$/.test('哈')) // true
console.log(/^哈+$/.test('哈哈')) // true
console.log(/^哈+$/.test('二哈很傻')) // false
console.log(/^哈+$/.test('哈很啥')) // false
// 量词 ? 类似 0或1次
console.log(/^哈?$/.test('')) // true
console.log(/^哈?$/.test('哈')) // true
console.log(/^哈?$/.test('哈哈')) // false
console.log(/^哈?$/.test('二哈很傻')) // false
console.log(/^哈?$/.test('哈很啥')) // false
// 量词{n} 写几,必须出现几次
console.log(/^哈{4}$/.test('哈')) //false
console.log(/^哈{4}$/.test('哈哈')) //false
console.log(/^哈{4}$/.test('哈哈哈哈')) // true
console.log(/^哈{4}$/.test('哈哈哈哈哈')) // false
console.log(/^哈{4}$/.test('哈哈哈哈哈哈')) // false
// 量词{n,} >=n
console.log(/^哈{4,}$/.test('哈')) //false
console.log(/^哈{4,}$/.test('哈哈')) //false
console.log(/^哈{4,}$/.test('哈哈哈哈')) // true
console.log(/^哈{4,}$/.test('哈哈哈哈哈')) // true
console.log(/^哈{4,}$/.test('哈哈哈哈哈哈')) // true
// 量词{n,m} >=n 并且 <=m 逗号左右两侧于万不能有空格
console.log(/^哈{4,6}$/.test('哈')) //false
console.log(/^哈{4,6}$/.test('哈哈')) //false
console.log(/^哈{4,6}$/.test('哈哈哈哈')) // true
console.log(/^哈{4,6}$/.test('哈哈哈哈哈')) // true
console.log(/^哈{4,6}$/.test('哈哈哈哈哈哈')) // true
console.log(/^哈{4,6}$/.test('哈哈哈哈哈哈')) // true
console.log(/^哈{4,6}$/.test('哈哈哈哈哈哈哈')) // false
字符类
[]
是匹配字符集合,后面的字符串只要包含abc
中任意一个字符,都返回true
// 字符类 [abc] 只能选一个
console.log(/^[abc]$/.test('a')) // true
console.log(/^[abc]$/.test('b')) // true
console.log(/^[abc]$/.test('c')) // true
console.log(/^[abc]$/.test('ab')) // false
console.log(/^[abc]{2}$/.test('ab')) // true
使用连字符表示一个范围,例如:[a-z]
表示 a 到z,26个英文字母都可以[a-zA-Z]
表示大小写都可以[0-9]
表示 0~9 的数字都可以
console.log(/^[a-z]$/.test('p')) // true
console.log(/^[A-Z]$/.test('p')) // false
console.log(/^[0-9]$/.test('3')) // true
console.log(/^[a-zA-Z0-9]$/.test('3')) // true
console.log(/^[a-zA-Z0-9]$/.test('L')) // true
console.log(/^[a-zA-Z0-9]{4,8}$/.test('L123abCB')) // true
// QQ号从10000开始,{重复次数}是重复最近那个[1-9]
console.log(/^[1-9][0-9]{4,}$/.test('19696000')) // true
[]
里面加上^
取反符号,例如:[^a-z]
匹配除了小写字母以外的字符
console.log(/^[^a-zA-Z0-9]$/.test('12ac')) // false
console.log(/^[^a-zA-Z0-9]$/.test('耷')) // true
.
匹配除换行符之外的任何单个字符
预定类
预定义指的是 某些常见模式的简写方式。
预定类 | 说明 |
\d | 匹配0-9之间的任一数字,相当于[0-9] |
\D | 匹配所有0-9以外的字符,相当于[^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] |
\W | 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_] |
\s | 匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f] |
\S | 匹配非空格的字符,相当于[^\t\r\n\v\f] |
案例:用户名验证案例
用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为6~16位。 Demo
分析:
① 首先准备好这种正则表达式模式
/^[a-ZA-Z0-9-_]{6,16}$/
② 当表单失去焦点就开始验证
③ 如果符合正则规范,则让后面的span
标签添加right
类
④ 如果不符合正则规范,则让后面的span
标签添加wrong
类
// 正则表达式 [-_]中特殊符号要写在最后面
const reg = /^[a-zA-Z0-9-_]{6,16}$/
const input = document.querySelector('input')
const span = input.nextElementSibling
// 表单失去光标事件
input.addEventListener('blur', function () {
if (reg.test(this.value)) {
span.innerHTML = '输入正确'
span.classList.add('right')
span.className = 'right'
} else {
span.innerHTML = '请输入6~16位英文数字下划线'
span.classList.add('error')
}
})
修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等。
i
是ignore的缩写,正则匹配时字母不区分大小写g
是global的缩写,匹配所有满足正则表达式的结果(全局)
console.log(/^java$/.test('java')) // true
console.log(/^java$/.test('JAVA')) // false
console.log(/^java$/i.test('JAVA')) // true
console.log(/^java$/i.test('Java')) // true
replace替换
console.log(/^java$/.test('java')) // true
console.log(/^java$/.test('JAVA')) // false
console.log(/^java$/i.test('JAVA')) // true
console.log(/^java$/i.test('Java')) // true
// g是全局替换,不然只能替换一个,i是匹配不区分大小写
const str = 'java是一门编程语言, 学完java工资很高'
const result = str.replace(/java/gi, '前端')
// const result = str.replace(/java|JAVA/g, '前端')
console.log(result)
// 前端是一门编程语言, 学完前端工资很高
案例:过滤敏感字
需求:要求用户不能输入敏感字 Demo
分析:
① 用户输入内容
② 内容进行正则替换查找,找到敏感词,进行**
③ 要全局替换使用修饰符g
const tx = document.querySelector('textarea')
const btn = document.querySelector('button')
const div = document.querySelector('div')
btn.addEventListener('click', function () {
// console.log(tx.value)
div.innerHTML = tx.value.replace(/激情|基情/g, '**')
tx.value = ''
})
综合案例
案例:小兔鲜页面注册
分析业务模块:Demo
① 发送验证码模块
- 用户点击之后,显示 05秒后重新获取,时间到了,自动改为重新获取
② 各个表单验证模块,(注意封装函数
verifyxxx
),失去焦点触发这个函数
- 正则
/^[a-zA-Z0-9-_]{6,9}$/
- 如果不符合要求,则出现提示信息,并
return false
中断程序- 否则 则返回
return true
- 之所以返回 布尔值,是为了 最后的提交按钮做准备
- 侦听使用
change
事件,当鼠标离开了表单,并且表单值发生了变化时触发(类似京东效果)手机号:
/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
验证码:/^\d{6}$/
密码框:/^[a-zA-Z0-9-_]{6,20}$/
③ 勾选已经阅读同意模块
- 添加类
.icon-queren2
则是默认选中样式 可以使用toggle
切换类④ 下一步验证全部模块:使用
submit
提交事件
- 只要上面有一个
input
验证不通过就不同意提交- 如果没有勾选同意协议,则提示 需要勾选
classList.contains()
看看有没有包含某个类,如果有则返回true
,么有则返回false
- 如果上面
input
表单 只要有模块,返回的是false
则阻止提交
// 模块一 发送验证码
// 1. 发送短信验证码
const code = document.querySelector('.code')
let flag = true // 通过一个变量来控制 节流阀
// 1.1点击事件
code.addEventListener('click', function () {
if (flag) {
flag = false
let i = 5
// 点击完成之后立即触发
code.innerHTML = `0${i}秒后重新获取`
let timerId = setInterval(function () {
i--
code.innerHTML = `0${i}秒后重新获取`
if (i === 0) {
clearInterval(timerId)
// 从新获取
code.innerHTML = '重新获取'
// 到时间了,可以开启变量开关
flag = true
}
}, 1000)
}
})
// 模块二 各个表单验证
// 1. 获取用户表单
const username = document.querySelector('[name=username]')
// 1.1 使用change事件
username.addEventListener('change', verifyName)
// 1.2 封装函数 verifyName
function verifyName() {
const span = username.nextElementSibling
// 1.3 定规则
const reg = /^[a-zA-Z0-9-_]{6,10}$/
// 1.4 账号表单输入不等于reg,则取反false执行下面的代码
if (!reg.test(username.value)) {
span.innerHTML = '输入不合法,请输入6~10位'
// 返回错误的结果 是不合法的
return false // 中断程序
}
// 1.5 合法就清空
span.innerHTML = ''
return true
}
// 模块三 验证手机号
// 1. 获取用户表单
const phone = document.querySelector('[name=phone]')
// 1.1 使用change事件
phone.addEventListener('change', verifyPhone)
// 1.2 封装函数 verifyName
function verifyPhone() {
const span = phone.nextElementSibling
// 1.3 定规则
const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
// 1.4 账号表单输入不等于reg,则取反false执行下面的代码
if (!reg.test(phone.value)) {
span.innerHTML = '输入不合法,请输入正确的11位手机号'
// 返回错误的结果 是不合法的
return false // 中断程序
}
// 1.5 合法就清空
span.innerHTML = ''
return true
}
// 模块四 验证验证码
// 1. 获取用户表单
const codeInput = document.querySelector('[name=code]')
// 1.1 使用change事件
codeInput.addEventListener('change', verifyCode)
// 1.2 封装函数 verifyName
function verifyCode() {
const span = codeInput.nextElementSibling
// 1.3 定规则
const reg = /^\d{6}$/
// 1.4 账号表单输入不等于reg,则取反false执行下面的代码
if (!reg.test(codeInput.value)) {
span.innerHTML = '输入不合法,请输入6位数字'
// 返回错误的结果 是不合法的
return false // 中断程序
}
// 1.5 合法就清空
span.innerHTML = ''
return true
}
// 模块五 验证密码
// 1. 获取用户表单
const password = document.querySelector('[name=password]')
// 1.1 使用change事件
password.addEventListener('change', verifyPassword)
// 1.2 封装函数 verifyName
function verifyPassword() {
const span = password.nextElementSibling
// 1.3 定规则
const reg = /^[a-zA-Z0-9-_]{6,20}$/
// 1.4 账号表单输入不等于reg,则取反false执行下面的代码
if (!reg.test(password.value)) {
span.innerHTML = '输入不合法,请输入6~20数字字母组成'
// 返回错误的结果 是不合法的
return false // 中断程序
}
// 1.5 合法就清空
span.innerHTML = ''
return true
}
// 模块六 密码的再次验证
// 1. 获取用户表单
const confirm = document.querySelector('[name=confirm]')
// 1.1 使用change事件
confirm.addEventListener('change', verifyConfirm)
// 1.2 封装函数 verifyName
function verifyConfirm() {
const span = password.nextElementSibling
// 1.4 账号表单输入不等于reg,则取反false执行下面的代码
if (confirm.value !== password.value) {
span.innerHTML = '两次密码输入不一致'
// 返回错误的结果 是不合法的
return false // 中断程序
}
// 1.5 合法就清空
span.innerHTML = ''
return true
}
// 模块七 我同意模块
const queren = document.querySelector('.icon-queren')
queren.addEventListener('click', function () {
// 切换类,原来有就删除,原来没有就添加
this.classList.toggle('icon-queren2')
})
// 模块八 提交模块
const form = document.querySelector('form')
form.addEventListener('submit', function (e) {
// 1. 判断是否勾选我同意模块,如果有 icon-queren2说明就勾选了,否则没勾选
if (!queren.classList.contains('icon-queren2')) {
alert('请勾选同意协议')
// 阻止提交
e.preventDefault()
}
// 2. 依次判断上面的每个框框 是否通过,只要有一个没有通过就阻止
if (!verifyName()) e.preventDefault()
if (!verifyPhone()) e.preventDefault()
if (!verifyCode()) e.preventDefault()
if (!verifyPassword()) e.preventDefault()
if (!verifyConfirm()) e.preventDefault()
})
案例:小兔鲜登录页面
模块一 tab切换 Demo
模块二 点击登录可以跳转页面
- 先阻止默认行为
- 如果没有勾选同意,则提示要勾选
required
属性不能空- 假设登录成功
- 把用户名记录到本地存储中
- 同时跳转到首页
location.href
小知识:表单required
属性是非空属性,用户没填,则会有提示。
<form>中autocomplete=”off”属性存在安全问题,一般关掉删掉,不给你记录。
tab_nav.querySelector('.active').classList.remove('active')
获取某个DOM节点的里面的clss类。并做一些样式操作
// 1. tab栏切换 事件委托
const tab_nav = document.querySelector('.tab-nav')
const pane = document.querySelectorAll('.tab-pane')
const username = document.querySelector('[name=username]')
// 1.1事件监听
tab_nav.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
// 取消上一个active
tab_nav.querySelector('.active').classList.remove('active')
// 当前元素添加 active
e.target.classList.add('active')
// 先干掉所有人
for (let i = 0; i < pane.length; i++)
pane[i].style.display = 'none'
}
// 让对应序号的大盒子显示
pane[e.target.dataset.id].style.display = 'block'
})
// 点击提交模块
const form = document.querySelector('form')
const agree = document.querySelector('[name=agree]')
form.addEventListener('submit', function (e) {
e.preventDefault()
// 判断是否勾选了复选框同意协议
if (!agree.checked) {
return alert('请勾选同意')
}
// 记录用户名到本地存储
localStorage.setItem('xtx-uname', username.value)
// 跳转到首页
location.href = './index.html'
})
案例:小兔鲜首页页面
第一,从登录页面跳转过来之后,自动显示用户名;Demo
第二,如果点击退出,则不显示用户名
最好写个渲染函数,因为一会的退出还需要用到
- 如果本地存储有记录的用户名,读取本地存储数据
- 需要把用户名写到第一个
li
里面 - 因为登录了,所以第二个里面的文字变为退出登录
- 需要把用户名写到第一个
- 如果本地存储没有数据,则复原为默认的结构
- 点击退出登录
- 删除本地存储对应的用户名数据
- 重新调用渲染函数即可
// 1、 获取第一个小li
const li1 = document.querySelector('.xtx_navs li:first-child')
const li2 = li1.nextElementSibling
// 2. 最好做个渲染函数 因为退出登录需要重新渲染
function render() {
// 2.1 读取本地的数据名
const uname = localStorage.getItem('xtx-uname')
// console.log(uname) // 打印用户名
if (uname) {
li1.innerHTML = `<a href="javascript:;"><i class="iconfont icon-user">${uname}</i></a>`
li2.innerHTML = `<a href="javascript:;">退出登录</a>`
} else {
li1.innerHTML = '<a href="./login.html">请先登录</a>'
li2.innerHTML = '<a href="./register.html">免费注册</a>'
}
}
render()
// 2. 点击退出登录
li2.addEventListener('click', function () {
// 删除本地存储的数据(用户名)
localStorage.removeItem('xtx-uname')
render()
})
原创文章,作者:霍欣标,如若转载,请注明出处:https://www.bigengwu.cn/xue/139.html