## 正则表达式
介绍
正则表达式(regular expression)是一种通过一系列描述信息编写模式,作用是通过这些信息,找到符合这些正则表达式条件的文本,从而做匹配,替换,截取等操作;正则表达式在js中也是对象。
使用场景
最常用的场景是表单验证,也是js最初诞生的作用。
语法
我们先定义规则,再去根据规则查找
那么如何定义规则呢?
/ /是正则表达式的字面量。变量名reg存储了一个正则对象,因为是对象。所以也可以用对象的方法提取里面的属性等。
现在找到怎么定义最基本的规则了,那么怎么查找呢,就要用到这个正则对象的一个方法test()
<script>
let regular = /瑾年/
let str ='这里是瑾年的学习博客'
let str1 ='体验未知,探索未知'
console.log( regular.test(str)) // true
console.log( regular.test(str1)) //false
console.log( regular.test('瑾年never say never')) // true
//因为regular里面就是/前端/,所以可以直接下面这种方法
console.log( /前端/.test('瑾年never say never')) // true
</script>
exec方法
reg.exec()方法和reg.test()一样是正则对象的一个方法,不同的是,如果没有找到,它会返回null,如果找到它会返回一个数组包含了一些信息
元字符
上面的/瑾年/就是普通字符,指定了瑾年两个字
而元字符则是具有一些特殊含义,比如规定用户只能输入26英文字母,普通字符的话要abcdefg……
而元字符只需要写成[a-z]即可
在实际运用中,正则表达式一般直接复制粘贴,因为网上有绝大部分现成的规则,但学懂肯定更好。
https://tool.oschina.net/regex
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
三种常用元字符
边界符
注意同时用^和$的精确匹配,只有开头结尾都是同一个字符,才是真
量词
量词是干嘛的呢,它是限定次数的,比如设置一个密码,你可以规定最大长度。
注意{n,m}这里面不要加空格
字符类
[abcdefg……..z]和连字符[a-z]是一样的效果,即用户必须包含里面的其中一个即可。
注意:
1-这个正则表达式也是有优先级的,如这个腾讯的,{4,}只管的了[0-9]管不了[1-9],这段表达式的意思就是qq第一位必须是1-9,后续位必须等于或超过四个且是0-9
2- console.log(/^a?$/.test(‘’)) //true
这里为什么是true呢?不是a要是在开头也是结尾吗?空字符如何实现?
其实是理解错误了,这里可以/^a?$/看作/^(a?)$/ 其中a?的意思就是可以一个a或者0
个a,所以可以相当于/^$/,即空字符开头结尾,所以结果为true
后面的量词只对最近的字符类生效。
注意:上图的字符类加了边界符,必须开头和结尾,那么只有选其中一个字母的时候,才会成立,如234成立,15不成立。
[a-zA-Z]一般表示26个字母不区分大小写,即变成了52个字母任填也能过
[a-zA-Z0-9]就是可以输入数字字母都可以。
[a-zA-Z0-9-_]也可以加上短横线和下划线,这样用户也可以输入这两个字符做账户或密码
案例验证用户名
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.right {
color: green;
}
.error {
color: red;
}
</style>
</head>
<body>
<input type="text" name="" id="" placeholder="请输入您的账户名">
<span></span>
<script>
let input = document.querySelector('input')
let text = input.nextElementSibling
input.addEventListener("blur", function () {
if (/^[a-zA-Z0-9-_]{6,16}$/.test(input.value)) {
text.innerHTML = "用户名可用"
text.className = 'right'
}
else {
text.innerHTML = "用户名必须大于6位小于16位"
text.className = 'error'
console.log(/^a-zA-Z0-9-_{6,16}$/.test(input.value))
console.log(input.value)
}
})
</script>
</body>
</html>
两个不同的^
原先学的肩括号是边界符一般加在最外面,如/^[a-z]$/
这里的^是取反符号,加在字符类里面,如/[ ^a-z]$/,这个的意思是除a-z以外的所有字符。
还有一个点. 是匹配除换行符之外的所有字符,如/^.{6,16}$/表示输入任意字符6-16个
字符类的更简洁写法
/^\d{4}-\d{2}-\d{2}$/这个的意思就算必须是2022-06-21这种格式,没错必须加上斜杠才算正确。
修饰符
修饰符是写在//的后面,如上的i表示不区分大小写,那么我test大写A也是得到true
g是global的意思,不仅限于选中符合正则表达式的第一个,而是匹配所有符合 条件的,下面的替换敏感词会用到。
修饰符的替换replace
这个意思就算从字符串里面找匹配正则表达式的内容,然后替换成其他文本。
案例过滤敏感词
1-这里的g是修饰符,如果不添加的话,如果文本有多个符合正则表达式的文本,如上的“激情”,那么只会替换一个。
2-如果要添加多个敏感词,用|隔开即可。
<body>
<textarea name="" id="" cols="30" rows="10"></textarea>
<p></p>
<button>提交</button>
<script>
let textarea = document.querySelector('textarea')
let p = textarea.nextElementSibling
let btn = p.nextElementSibling
btn.addEventListener('click', function () {
p.innerHTML = textarea.value.replace(/逗逼|愚蠢/g, '大帅哥')
})
</script>
</body>
综合案例小兔仙表单验证
1-需求7那种单选框同意条款,我们自己一般做不成那么好看的效果,所以一般使用i标签通过iconfont类来渲染,使用ClassList.toggle()来实现。
2-需求八中,当所有的input中有一个是false,即不提交,需要用到e.preventDefault()来阻止默认事件。
其中注意,提交事件是写在form上面,而不是写在那个提交按钮上面,提交的是form不是按钮。
这个验证模块,即判断i标签有没有那个勾选的样式类名即可,用到了新知识,classList.contain(‘类名’),有返回true,没有返回fasle
在表单验证中,我们一般使用change事件而不是blur事件,只要当input内容value改变,再失去焦点就进行判断。
blur事件是失去焦点就判断,但是当用户根本没有输入,也判断了,实际开发中不需要这样。
还有一个input事件,只要输入就触发。
其中还可以用css属性选择器去选中不同的输入框,因为表单里不同的input的name肯定不一样,因为前后端交互,需要用name来交换数据。
问题:
1-点击获取验证码的按钮,直接页面刷新了,自然没了效果,困扰我很久。
原因:按钮如果是表单的<button>
标签,如果没有指定type属性,则其type属性默认为type=submit。所以每次点击登录button后都会执行提交表单的操作,表单操作默认有刷新页面的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
margin: 0px auto;
width: 600px;
background-color: pink;
}
.container div {
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<form>
<div class="username">
<input type="text" placeholder="输入用户名" name="username">
<span class="msg"> </span>
</div>
<div class="phone">
<input type="tel" placeholder="输入手机号码" name="phone">
<span class="msg"> </span>
</div>
<div class="verify_code">
<input type="text" placeholder="短信验证码" name="verify_code">
<button class="get_code_btn" type="button">获取验证码</button>
<span class="msg">验证码正确 </span>
</div>
<div class="password">
<input type="password" placeholder="请输入6-20位的字母,数字,符合组合" name="password">
<span class="msg">密码格式正确</span>
</div>
<div class="password_confirm">
<input type="password" placeholder="重复密码" name="password_confirm">
<span class="msg">密码一致</span>
</div>
<div class="rules">
<input type="radio" name="" id="" name="rules">
已阅读并同意<i>《用户服务协议》</i>
</div>
<div class="submit">
<button class="submit_btn">注册</button>
<!-- <a class="submit" href="javascript:;">下一步</a> -->
</div>
</form>
</div>
<script>
// 验证码
let get_code_btn = document.querySelector('.get_code_btn')
get_code_btn.addEventListener('click', function () {
get_code_btn.innerText = `05s后重新获取`
let num = 5
let timer = setInterval(function () {
num--
get_code_btn.innerHTML = `0${num}秒后重新获取`
if (num == 0) {
clearInterval(timer)
get_code_btn.innerHTML = `重新获取`
}
}, 1000)
})
// 验证用户名
let username_value = document.querySelector('[name=username]')
// 因为最后注册按钮也需要用到此验证函数,所以封装一下
username_value.addEventListener('input', verifyUserName)
function verifyUserName() {
let reg = /^[a-zA-Z0-9-_]{6,10}$/
let msg = username_value.nextElementSibling
if (!reg.test(username_value.value)) {
msg.innerHTML = '昵称长度为6到10个字符'
// 这里为什么要返回false和true呢,因为注册按钮需要用到,只有所有验证都是true,才通过.
return false
}
msg.innerText = '用户名可用'
return true
}
// 验证手机号码
let phone = document.querySelector('[name=phone]')
phone.addEventListener('input', verifyUserphone)
function verifyUserphone() {
let reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
let msg = phone.nextElementSibling
if (!reg.test(phone.value)) {
msg.innerHTML = '手机号码格式不正确'
return false
}
msg.innerText = '手机号码可用'
return true
}
// 其他的input验证如短信和密码都同上,换一下正则即可.
// 注册按钮提交
let form = document.querySelector('form')
form.addEventListener('submit', function (ev) {
if (!(verifyUserName() && verifyUserphone())) {
console.log(verifyUserName())
ev.preventDefault()
alert('请正确输入所有信息')
}
})
</script>
</body>
</html>