1-正则表达式介绍
1.1什么是正则表达式
正则表达式是一个用于对字符串实现逻辑匹配运算的对象
1.2.正则表达式的作用
- 按照某种规则来匹配字符串,而正则表达式就是制定这个规则
正则表达式验证常用表单文本(手机、邮箱、qq、座机、姓名)
1.正则表达式 :RegExp (regular expression) 是ECMAScript内置对象
2.作用 :对 字符串进行逻辑匹配 运算
3.使用流程 :
(1)创建正则对象 : let reg = new RegExp('正则')
(2)调用正则对象的test方法: reg.test('需要校验的字符串')
true : 校验通过
false : 校验不通过
1.3 定义正则表达式语法:
const 变量名= /表达式/
其中 / / 是正则表达式字面量
const reg=/前端/

(1)js中几乎所有的内置对象,都是通过new来创建的
new Date()
new RegExp()
new Array()
new Object()

(2)js中有三种内置对象有简写语法
数组: []
对象: {}
正则: /正则/
案例
正则: 检测字符串有没有a
let reg = new RegExp('a')
console.log( reg.test('abc123') )
console.log( reg.test('bc123') )
console.log( /a/.test('sfsfsfs') )
正则: 检测字符串有没有 "前端"
const str = '前端,后端,测试'
const reg = /前端/
console.log(reg.test(str))
2. 正则表达式语法由两部分组成
1.原义文本字符 : 字符串本身的含义
* PS : 别多想,写什么就是什么。想的越多,错的越离谱
2.元字符 : 改变了字符串本身的含义, 类似于js中的关键字
[] {} () . \ + ? * ^ $ |
[] : 字符类
/abc/ : 原义文本字符。 检测字符串有没有 abc
/[abc]/ : 字符类。 将a 或 b 或 c归为一类,满足任意一个即可.
说人话: 检测字符串中有没有 a 或 b 或 c
/[^abc]/ : 反向类。 将不是a 或 不是b 或 不是c的归为一类,满足任意一个即可。
说人话: 检测字符串中有没有除 abc之外的任意字符
/[abc]/ : 检测字符串中有没有 a 或 b 或 c ,只要字符串有 a 或 b 或 c 中任意一个即可
console.log(/[abc]/.test('a1b2c3'))
console.log(/[abc]/.test('abc123'))
console.log(/[abc]/.test('a123456'))
console.log(/[abc]/.test('123456'))
console.log(/[abc]/.test('abcabc'))
/[^abc]/ : 检测字符串中有 ‘不是abc’ 的任意字符
console.log(/[^abc]/.test('a1b2c3'))
console.log(/[^abc]/.test('abc123'))
console.log(/[^abc]/.test('a123456'))
console.log(/[^abc]/.test('123456'))
console.log(/[^abc]/.test('abcabc'))

[]表示里面的任意一个字符
console.log(/[abcd]/.test('bcd'))
console.log(/[abcd]/.test('acd'))
console.log(/[abcd]/.test('ecd'))
console.log(/[abcd]/.test('efg'))
表示必须以a,b,c,d开头才能匹配
console.log(/^[abcd]/.test('bcd'))
console.log(/^[abcd]/.test('acd'))
console.log(/^[abcd]/.test('ecd'))
console.log(/^[abcd]/.test('efg'))
[a-z] 表示 a 到 z 26个英文字母都可以
console.log(/^[a-z]/.test('a10'))
console.log(/^[a-zA-Z]/.test('a10'))
需求: 检测字符串中有没有数字字符
/[0123456789]/ : 有没有数字
需求: 检测字符串中有没有字母
/[abcdefghijklmnopqrstuvwxyz]/ : 检测字符串中有没有字母
1.范围类
/[0-9]/ : 检测有没有数字
/[a-z]/ : 检测有没有小写字母
/[A-Z]/ : 检测有没有大写字母
2.范围类特点
2.1 范围类是一个闭区间 : /[5-8]/ : 包含5,也包含8
2.2 范围类可以连写: /[0-9a-zA-Z]/ : 大小写字母+数字
2.3 范围类一定是 右边 > 左边 (依据ASCII码)
[5-8] : 正确
[8-5] : 报错
console.log( /[0-9]/.test('abc123') )
console.log( /[a-z]/.test('abc123') )
console.log( /[A-Z]/.test('abc123') )
/黑马/ : 检测字符串中有没有黑马 。
不是有黑 或 有 马,也不是有黑,且有马。 就是检测有没有黑马
console.log( /黑马/.test('我喜欢黑色') )
console.log( /黑马/.test('一匹黑色的马') )
console.log( /黑马/.test('黑马程序员') )
console.log(/哈/.test('哈'))
console.log(/^你好/.test('你好'))
console.log(/^你好$/.test('你好'))
console.log(/^你好你好$/.test('你好'))
console.log(/^你好大家好$/.test('你好'))
+表示重复一次或者更多次
console.log(/^哈+$/.test(''));
console.log(/^哈+$/.test('哈'));
console.log(/^哈+$/.test('哈哈哈'))
?表示重复0次或者一次
console.log(/^哈?$/.test(''));
console.log(/^哈?$/.test('哈'));
console.log(/^哈?$/.test('哈哈哈'))
表示2次到3次之间
console.log(/^哈{2,3}$/.test(''));
console.log(/^哈{2,3}$/.test('哈哈'));
console.log(/^哈{2,3}$/.test('哈哈哈'))
console.log(/^哈{2,3}$/.test('哈哈哈哈'))
表示至少出现2次
console.log(/^哈{2,}$/.test(''))
console.log(/^哈{2,}$/.test('哈哈'))
console.log(/^哈{2,}$/.test('哈哈哈'))


预定义类: 正则表达式提供好的用来匹配常见的字符类
预定义类 等价类 含义
. [^\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] 非单词字符
/\d/ : 检测有没有数字 与 /[0-9]/ 等价
console.log( /\d/.test('abc123') )
/\w/ : 单词字符 检测单词(大小写字母 数字 下划线_)。 等价于 [a-zA-Z_0-9]
console.log( /\w/.test('abc_') )
console.log( /\w/.test('+-*/[]()') )
console.log( /\w/.test('()[]_') )
console.log( /\w/.test('=+-') )
原义文本字符: /abc/ 检测字符串abc
字符类 : /[abc]/ 检测a或b或c任意字符
反向类 : /[^abc]/ 检测不是 a或b或c任意字符
边界 : /^abc/ 在正则中,有时候一个元字符可能有两种含义(类似于js的+)
console.log( /^abc/.test('a1b2c3'))
console.log( /^abc/.test('abc123'))
console.log( /^abc/.test('abcabc'))
console.log( /^abc/.test('123abc'))
console.log( /abc$/.test('a1b2c3'))
console.log( /abc$/.test('abc123'))
console.log( /abc$/.test('abcabc'))
console.log( /abc$/.test('123abc'))
console.log( /^abc$/.test('a1b2c3'))
console.log( /^abc$/.test('abc123'))
console.log( /^abc$/.test('abcabc'))
console.log( /^abc$/.test('123abc'))
console.log( /^abc$/.test('abc'))
console.log( /^\d$/.test('123'))
console.log( /^\d$/.test('456'))
console.log( /^\d$/.test('77'))
console.log( /^\d$/.test('7'))
console.log( /^\d$/.test('8'))
console.log( /^\d$/.test('9'))
console.log( /^\d$/.test('0'))
量词作用: 检测字符出现的次数
? 出现零次或一次(最多出现一次 <=1)
+ 出现一次或多次(至少出现一次 >=1)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n-m次
{n,} 出现至少n次(>=n)
/\d?/ : 匹配 零次或一次(最多出现一次 <=1)
console.log('1234567890abc'.replace(/\d?/,'X'))
console.log('a1234567890abc'.replace(/\d?/,'X'))
/\d+/ : 匹配 出现一次或多次(至少出现一次 >=1)
console.log('1234567890abc'.replace(/\d+/,'X'))
console.log('a1234567890abc'.replace(/\d+/,'X'))
/\d*/ : 匹配 出现零次或多次(任意次)
console.log('1234567890abc'.replace(/\d*/,'X'))
console.log('a1234567890abc'.replace(/\d*/,'X'))
/\d{5}/ : 匹配5次
console.log('1234567890abc'.replace(/\d{5}/,'X'))
/\d{5,8}/ : 匹配5-8次
console.log('1234567890abc'.replace(/\d{5,8}/,'X'))
/\d{5,}/ : 匹配>=5次
console.log('1234567890abc'.replace(/\d{5,}/,'X'))
console.log( '123456789'.replace(/\d?/,'X'))
console.log( '123456789'.replace(/\d+/,'X'))
console.log( 'a123456789'.replace(/\d+/,'X'))
console.log( 'a123456789'.replace(/\d*/,'X'))
console.log( 'a123456789'.replace(/\d{5}/,'X'))
console.log( 'a123456789'.replace(/\d{5,8}/,'X'))
console.log( 'a123456789'.replace(/\d{5,}/,'X'))


分组
在正则中有两种含义
1.分组 : 把多个字符归为一组,用于量词
2.提升优先级 : 让 | 只匹配小括号内部的字符,提升|的优先级
1.分组 : 把多个字符归为一组,用于量词
需求:检测 三次 love
/love{3}/ : 检测 lov + e出现3次,e后面必须连续出现e
/(love){3}/ : 检测 (love) 出现三次,love后面必须连续出现love
/love{3}/ : 检测 lov + e出现3次,e后面必须连续出现e
console.log( /love{3}/.test('lovelovelove'))
console.log( /love{3}/.test('loveee'))
/(love){3}/ : 检测 (love) 出现三次,love后面必须连续出现love
console.log( /(love){3}/.test('lovelovelove'))
console.log( /(love){3}/.test('loveeee'))
2.提升优先级 : 用于 |
需求: 检测 love 或 live
/lo|ive/ : 检测 lo 或 ive ,表示检测代码里面有没有lo 或 ive
/l(o|i)ve/ : 检测 l + o或i + ve ,表示检测代码里面有没有love 或 live
/lo|ive/ : 检测 lo 或 ive ,表示检测代码里面有没有lo 或 ive
console.log( /lo|ive/.test('lo123'))
console.log( /lo|ive/.test('ive123'))
console.log( /lo|ive/.test('love123'))
console.log( /lo|ive/.test('live123'))
/l(o|i)ve/ : 检测 l + o或i + ve ,表示检测代码里面有没有love 或 live
console.log( /l(o|i)ve/.test('lo123'))
console.log( /l(o|i)ve/.test('ive123'))
console.log( /l(o|i)ve/.test('love123'))
console.log( /l(o|i)ve/.test('live123'))
修饰符
1.修饰符 : 对正则表达式起到修饰的作用
g : global 全局匹配
i : intensity 不区分大小写
2.修饰符语法: /正则表达式/修饰符
new RegExp('正则','修饰符')
把代码a123A456aaAA里面的 a 替换成 X
(1) /a/ : 默认情况下,正则只能第一个字符
console.log( 'a123A456aaAA'.replace(/a/,'X') )
把代码a123A456aaAA里面的 a 替换成 X
(2) /a/g : 匹配所有的a
console.log( 'a123A456aaAA'.replace(/a/g,'X') )
把代码a123A456aaAA里面的 A 替换成 X
(1) /A/ : 默认情况下,正则区分大小写,并且只能替换一个A
console.log( 'a123A456aaAA'.replace(/A/,'X') )
把代码a123A456aaAA里面的 A 替换成 X
(2) /A/i : 不区分大小写 a 和 A都可以,默认情况下,只能替换第一个a
console.log( 'a123A456aaAA'.replace(/A/i,'X') )
修饰符是可以同时使用
/a/ig : 不区分大小写 + 全局匹配 替换所有的a
console.log( 'a123A456aaAA'.replace(/A/ig,'X') )
常用正则表达式总结
1.手机号正则
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$
2.验证码
/^\d{6}$/
3.账号密码 6-20位: 大小写字母, 下划线_
/^\w{6,20}$/
4.邮箱
/^\w+[@]\w+\.\w+(\.\w+)?$/
5.身份证
/^\d{17}(x|\d)$/

<script>
const str = 'hello帅哥,hello小可爱,Hello小哥哥'
const reg = /hello/gi
const res = str.replace(reg, '你好')
console.log(res)
</script>

案例
<body>
<textarea></textarea>
<div></div>
<script>
const tx = document.querySelector('textarea')
tx.addEventListener('blur', function () {
const reg = /基情|激情/g
const res = tx.value.replace(reg, '**')
tx.nextElementSibling.innerHTML = res
})
</script>
</body>
案例
<style>
span {
display: inline-block;
width: 250px;
height: 30px;
vertical-align: middle;
line-height: 30px;
padding-left: 15px;
}
.error {
color: red;
background: url(./images/error1.png) no-repeat left center;
}
.right {
color: green;
background: url(./images/right.png) no-repeat left center;
}
</style>
</head>
<body>
<input type="text">
<span></span>
<script>
const reg = /^[\u4e00-\u9fa5]{2,8}$/
const input = document.querySelector('input')
input.addEventListener('blur', function () {
const span = this.nextElementSibling
if (reg.test(this.value)) {
span.className = 'right'
span.innerHTML = '输入正确'
} else {
span.className = 'error'
span.innerHTML = '输入不合法'
}
})
</script>
</body>
案例
<style>
span {
display: inline-block;
width: 250px;
height: 30px;
vertical-align: middle;
line-height: 30px;
padding-left: 15px;
}
.error {
color: red;
background: url(./images/error1.png) no-repeat left center;
}
.right {
color: green;
background: url(./images/right.png) no-repeat left center;
}
</style>
</head>
<body>
<input type="text">
<span></span>
<script>
const input = document.querySelector('input')
input.addEventListener('blur', function () {
const reg = /^[a-zA-Z0-9-_]{6,16}$/
const span = this.nextElementSibling
if (reg.test(this.value)) {
span.className = 'right'
span.innerHTML = '输入的内容合法'
} else {
span.className = 'error'
span.innerHTML = '用户名必须合法'
}
})
</script>
</body>
放大镜
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 350px;
height: 350px;
margin: 100px;
border: 1px solid #ccc;
position: relative;
}
.big {
width: 400px;
height: 400px;
position: absolute;
top: 0;
left: 360px;
border: 1px solid #ccc;
overflow: hidden;
display: none;
}
.mask {
width: 175px;
height: 175px;
background: rgba(255, 255, 0, 0.4);
position: absolute;
top: 0;
left: 0;
cursor: move;
display: none;
}
.small {
position: relative;
}
.box img {
vertical-align: top;
}
#bigBox > img {
position: absolute;
}
</style>
<div class="box" id="box">
<div class="small" id="smallBox">
<img src="images/001.jpg" width="350" alt="" />
<div class="mask" id="mask"></div>
</div>
<div class="big" id="bigBox">
<img id="bigImg" src="images/0001.jpg" width="800" alt="" />
</div>
</div>
</body>
<script>
/* 需求分析:切入点交互
1.鼠标移入小盒子small:显示大盒子big与遮罩层mask
2.鼠标移出小盒子small:隐藏大盒子big与遮罩层mask
3.鼠标移动小盒子small:
a.mask跟随鼠标移动
b.鼠标在mask中心
c.mask边界检测
d.大盒子的图片对应移动
* 假如mask是50px*50px,大盒子是100px*100px,鼠标每移动1px,大盒子图片移动2px
* 100 / 50 * 1 = 2
*/
//获取元素
let box = document.querySelector('#box')//父盒子
let smallBox = document.querySelector('#smallBox')//小盒子
let mask = document.querySelector('#mask')//遮罩层
let bigBox = document.querySelector('#bigBox')//大盒子
let bigImg = document.querySelector('#bigImg')//大图片
//注册点击事件,鼠标移入
smallBox.onmouseenter = function(){
bigBox.style.display = 'block'
mask.style.display = 'block'
}
//注册点击事件,鼠标移出
smallBox.onmouseleave = function(){
bigBox.style.display = 'none'
mask.style.display = 'none'
}
//注册点击事件,鼠标移动
smallBox.onmousemove = function(e){
/**
红线:鼠标触发点到页面边缘的距离 e.pageX
绿线:父盒子左边框到页面边缘的距离 box.offsetLeft
蓝线:鼠标触发点到小盒子边缘的距离 = 红线 - 绿线
*/
let x = e.pageX - box.offsetLeft
let y = e.pageY - box.offsetTop
console.log(x,y)
console.log(mask.offsetWidth)
//鼠标在mask中心的位置 :让x和y往左上角偏移 mask宽高的一半
x -= mask.offsetWidth/2
y -= mask.offsetHeight/2
//mask只能在小盒子里面移动
/**
0 < x < smallBox宽度350-mask宽度175
0 < y < smallBox高度350-mask高度175
*/
x = x < 0 ? 0 : x
x = x > 175 ? 175 : x
y = y < 0 ? 0 : y
y = y > 175 ? 175 : y
mask.style.left = x + 'px'
mask.style.top = y + 'px'
bigImg.style.left = -x * bigBox.offsetWidth/mask.offsetWidth + 'px'
bigImg.style.top = -y * bigBox.offsetWidth/mask.offsetWidth + 'px'
}

