正则表达式
是一种模式:用于匹配字符串的模式
创建正则对象
构造函数方式
let reg = new RegExp('正则表达式模式')
字面量方式
let reg =/正则表达式模式/ 正则
const str = 'Dgfhfgh254bhku289fgdhdy675gfh'
const reg = /\d+/g // \d+ -> +限定前面的\d数字出现1次或更多次 -> >=1
let arr = str.match(reg)
console.log(arr) // ['254', '289', '675']
常用方法
test
作用:正则去匹配字符串,如果匹配成功返回true,不成功返回false
正则.test(字符串) => true/false
const str = 'abcdef' // 字符串
const reg = /c/ // 正则
let isOk = reg.test(str) //
alert(isOk)
search
作用:正则去匹配字符串,如果匹配成功,就返回匹配成功的位置,如果匹配失败就返回-1
字符串.search(正则)
const str = 'abcdef'
const reg = /c/
let index = str.search(reg)
alert(index) //2
match
作用:正则去匹配字符串,如果匹配成功返回数组,不成功返回null
字符串.match(正则)
const str = 'Dgfhfgh254bhku289fgdhdy675gfh'
const reg = /\d+/g
let arr = str.match(reg)
//let arr = reg.exec(str)
console.log(arr) // ['254', '289', '675']
replace
作用:正则去匹配字符串,匹配到的字符被新字符替换,返回替换后的新字符串
字符串.replace(正则,'新字符')
const str = 'abcdef'
const reg = /b/
let newStr = str.replace(reg, '*') //a*cdef
console.log(newStr)
exec
作用:正则去匹配字符串,如果匹配成功返回匹配成功的数组,以及匹配成功的第一个元素的index,不成功返回null
正则.exec(字符串)
const str = 'Dgfhfgh254bhku289fgdhdy675gfh'
const reg = /\d+/ //+ 至少出现一次
// let arr = str.match(reg)
let arr = reg.exec(str)
console.log(arr) // ['254', 7]
正则字符
普通字符就是a~z、0~9这类常见的字符。其中特殊字符又称为“元字符”。
/*
用正则表达式匹配的是中国的电话号码,以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字。
如: 028-88888888
写一个正则表达式,与给定的电话号码字符串匹配,判断是不是满足座机电话号
以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字。
*/
const phone1 = '128-1234567890'
const phone2 = '028-12345678'
const reg = /^0\d{2}-\d{8}$/ // 匹配座机电话模式 // 量词-限定符
let isOk = reg.test(phone2)
alert(isOk)
定位符
限定某些字符出现的位置
function test1(){
const str = 'There once was a man from NewYork this is'
// const str = 'once upon a time'
// const reg = /^once/ //从once开始
const reg = /NewYork$/ //从这里结束
console.log(reg.test(str))
}
test1()
修饰符
g: global 全文搜索,不添加,搜索到第一个匹配停止
i: ignore case 忽略大小写,默认大小写敏感
m: multiple lines 多行搜索
const str = 'Dgfhfgh254bhku289fgdhdy675gfh'
const reg = /\d+/g //跟在/ /后面
let arr = str.match(reg)
//let arr = reg.exec(str)
console.log(arr) // ['254', '289', '675'] //没有g就只有254
特殊转义符
- \f 匹配换页符
- \n 匹配换行符
- \r 匹配回车符
- \t 匹配制表符
- \v 匹配垂直制表符
- \\ 匹配\
- \" 匹配 "
- \' 匹配 '
- . -> 除换行符外的任意字符
- \. -> 匹配.
- 选择符
- | [a|b]
练习
/**
* 1.已知邮箱字符串'zhousir028@163.com'写正则匹配该邮箱字符串是否符合邮箱格式?
邮箱格式要求:
1. 必须包含@符号
2. @符号左右两边可以字母或数字或字母数字组合
3. 以.com结尾
*
*/
function test1() {
const email = 'zhousir028@qq.com'
const reg = /[0-9a-zA-Z]+@[0-9a-zA-Z]+\.com$/
if(reg.test(email)){
alert('正确邮箱格式')
}else{
alert('错误的邮箱格式')
}
}
// test1()
/*
2. 已知密码字符串'Zhousir12345' 写正则匹配密码是否符合密码强度规则?
密码强度规则:
1. 必须是大写字母开头
2. 密码包含字母和数字
3. 至少8位
*/
function test2() {
const password = 'ZHousir12'
const reg = /[A-Z][0-9a-zA-Z]{7,}/
if(reg.test(password)){
alert('正确密码格式')
}else{
alert('错误的密码格式')
}
}
// test2()
/*
3. 已知手机字符串'18012345678' 匹配中国手机号是否正则
中国手机号规则: 1. 以1开头
2.第二位是 3或5或8
3. 总共11位
*/
function test3() {
const phone = '13012345678'
const reg = /^1[3|5|8]\d{9}$/
if(reg.test(phone)){
alert('正确手机格式')
}else{
alert('错误的手机格式')
}
}
// test3()
/*
4. 用正则表达式匹配的是中国的电话号码,以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字
*/
function test4() {
}
/*
5. 将字符串中单词is替换成 'are'字符串如下:
'He is a boy, This is a dog.Where is she?'
*/
function test5() {
const str = 'He is a boy, This is a dog.Where is she?'
const reg = /\bis\b/g
let newStr = str.replace(reg,'are')
console.log(newStr);
}
test5()
非贪婪模式
const str = '123456789'
const reg = /\d{3,6}?/
let newStr = str.replace(reg, '*')
console.log(newStr)
分组与反向引用
分组:
const str = 'aabcdef'
const reg = /a+/
const str = 'abcdefabc'
const reg = /(abc)+/g
反向引用
$1 -> abc
const str = '2022-09-05' -> 09/05/2022
const reg = /(\d{4})-(\d{2})-(\d{2})/
$1 $2 $3
$2/$3/$1 -> 09/05/2022
思路: 匹配日期时间,分组后反向引用分组内容重组日期时间格式
const str = '2022-09-05' //-> 09/05/2022
const reg = /(\d{4})-(\d{2})-(\d{2})/
let newStr = str.replace(reg,'$2/$3/$1')
console.log(newStr)
轮播效果
元素运动
<div></div>
<script>
const box = document.querySelector('div')
/*
点击区块向右运行200px
*/
function test1() {
let distance = 200
box.addEventListener('click', function () {
box.style.left = `${distance}px`
})
}
// test1()
/*
平滑运动到200距离
*/
function test2() {
box.style.left = window.getComputedStyle(box).left // 获取非行间样式left值作为初始值
let init = parseInt(box.style.left) // 初始位置
let distance = 200 // 移动距离
let goal = init + distance // 目标位置
box.addEventListener('click', function () {
const timer = setInterval(function () {
if (parseInt(box.style.left) == goal) {
clearInterval(timer)
} else {
box.style.left = parseInt(box.style.left) + 20 + 'px'
console.log(box.style.left)
}
}, 50)
})
}
// test2()
/*
计算元素每次运动距离
总距离offsset 每次移动距离?
----- = --------------
总时间1000 每次移动时间-速度 rate
distance = offset * rate / time
*/
function test3() {
box.style.left = window.getComputedStyle(box).left // 获取非行间样式left值作为初始值
let init = parseInt(box.style.left) // 初始位置
let offset = 200 // 偏移量-移动总距离
let time = 1300 // 总时间
let rate = 50 // 速度
let distance = (offset * rate) / time // 每次移动距离
console.log('distance ', distance) // 10
let goal = init + offset // 目标位置 400
box.addEventListener('click', function () {
const timer = setInterval(function () {
if (parseInt(box.style.left) == goal || goal - parseInt(box.style.left) < distance) {
box.style.left = goal + 'px' // 如果当前位置与目标位置的距离小于移动的距离,直接到达目标位置
clearInterval(timer)
} else {
box.style.left = parseInt(box.style.left) + distance + 'px'
console.log(box.style.left)
}
}, rate)
})
}
test3()
* {
padding: 0;
margin: 0;
}
div {
position: absolute;
top: 0;
left: 200px;
width: 100px;
height: 100px;
background-color: skyblue;
}
元素左右运行
<div></div>
<script>
const box = document.querySelector('div')
/*
计算元素每次运动距离
总距离offsset 每次移动距离?
----- = --------------
总时间1000 每次移动时间-速度 rate
distance = offset * rate / time
*/
function test3() {
box.style.left = window.getComputedStyle(box).left // 获取非行间样式left值作为初始值
let init = parseInt(box.style.left) // 初始位置
let offset = 200 // 偏移量-移动总距离, 正的:向右移, 负向左移
let time = 1300 // 总时间
let rate = 50 // 速度
let distance = (offset * rate) / time // 每次移动距离
console.log('distance ', distance) // -10 7
let goal = init + offset // 目标位置 400
box.addEventListener('click', function () {
const timer = setInterval(function () {
if (parseInt(box.style.left) == goal || Math.abs(Math.abs(goal) - Math.abs(parseInt(box.style.left))) < Math.abs(distance)) {
box.style.left = goal + 'px' // 如果当前位置与目标位置的距离小于移动的距离,直接到达目标位置
clearInterval(timer)
} else {
box.style.left = parseInt(box.style.left) + distance + 'px'
console.log(box.style.left)
}
}, rate)
})
}
test3()
* {
padding: 0;
margin: 0;
}
div {
position: absolute;
top: 100px;
left: 600px;
width: 100px;
height: 100px;
background-color: skyblue;
}
封装运动函数
<div></div>
<p></p>
<script>
const divEle = document.querySelector('div')
divEle.addEventListener('click',function(){
move(divEle,400)
})
const pEle = document.querySelector('p')
pEle.addEventListener('click',function(){
move(pEle,-300)
})
/*
运动函数
ele 运动元素
offset 是运动总距离,偏移量 正向右,负向左
*/
function move(ele, offset) {
let time = 1000 // 总时间
let rate = 50 // 速度
let distance = (offset * rate) / time // 每次移动距离
//初始化当前位置
ele.style.left = window.getComputedStyle(ele).left
let init = parseInt(ele.style.left)
// 计算目标位置
let goal = init + offset
const timer = setInterval(function () {
if (parseInt(ele.style.left) == goal ||
Math.abs(Math.abs(goal) - Math.abs(parseInt(ele.style.left))) < Math.abs(distance)
) {
// 如果当前位置与目标位置的距离小于移动的距离,直接到达目标位置
ele.style.left = goal + 'px'
clearInterval(timer)
} else {
ele.style.left = parseInt(ele.style.left) + distance + 'px'
}
}, rate)
}
</script>
* {
padding: 0;
margin: 0;
}
div {
position: absolute;
top: 100px;
left: 600px;
width: 100px;
height: 100px;
background-color: skyblue;
}
p{
position: absolute;
top: 300px;
left: 600px;
width: 80px;
height: 80px;
background-color: pink;
}