Web APIs
正则表达式
介绍
- 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。
- 在 JavaScript中,正则表达式也是对象
- 通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。
正则表达式在 JavaScript中的使用场景:
- 例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)
- 比如用户名:
/^[a-z0-9_-]{3,16}$/ - 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
总结
- 正则表达式是什么?
- 是用于匹配字符串中字符组合的模式
- 正则表达式有什么作用?
- 表单验证 (匹配)
- 过滤敏感词 (替换)
- 字符串中提取我们想要的部分 (提取)
1. 为什么需要正则表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<!-- 合法字符是指: a-z A-Z 0-9 _ -->
用户名:
<input
class="username"
type="text"
placeholder="请输入用户名,不能包含特殊符号"
/>
<br />
密码:
<input type="text" placeholder="请输入3到16位的密码" class="password" />
<br />
手机号:
<input type="text" class="phone" placeholder="请填写11位的手机号" /> <br />
邮箱:<input type="text" class="email" /> <br />
身份证号码:
<input type="text" class="userId" placeholder="请输入合法的身份证号" />
<br />
<button>提交</button>
<script>
let btn = document.querySelector('button')
let username = document.querySelector('.username')
let password = document.querySelector('.password')
let phone = document.querySelector('.phone')
let emailEle = document.querySelector('.email')
let userId = document.querySelector('.userId')
btn.addEventListener('click', function() {
// 如果用户数据输入不合法,则给出提示,且不进行处理
let name = username.value
let pass = password.value
let phoneNum = phone.value
let email = emailEle.value
let id = userId.value
// 用户名至少一位,且不能包含特殊符号
if (!/^\w+$/.test(name)) {
alert('用户名输入不合法')
return
}
if (!/^\w{3,16}$/.test(pass)) {
alert('密码输入不合法')
return
}
if (!/^1[35789]\d{9}$/.test(phoneNum)) {
alert('手机号输入不合法')
return
}
// aaa@qq.com b@126.com wuhu@itcast.cn
// \ 转义符:将元字符当成普通字符进行处理
if (!/^\w+[@]\w+\.[a-zA-Z]{2,3}$/.test(email)) {
alert('邮箱号输入不合法')
return
}
if (!/^[1-6]\d{16}[0-9Xx]$/.test(id)) {
alert('身份证号输入不合法')
return
}
// 提交操作
alert('我去提交了')
})
</script>
</body>
</html>
2. 基本语法
- 定义规则
let reg = /abc/; - 查找
console.log(reg); - 判断是否有符合规则的字符串:
- test() 方法 用来查看正则表达式与指定的字符串是否匹配
- 语法: reg.test(被检测的字符串)
<script>
// 匹配:校验,主要是判断有没有,或者是否匹配
// 提取:提取符合正则规则的字符串
// 替换:定义需要被替换的字符串的匹配规则
let str = 'kljghjkl;kjhgafhjkl'
// 判断是否包含a【这个字符
// 1.定义正则 -- 创建一个正则对象,用来定义校验规则
// 以下规则说明:它要匹配是否有a这个字符
let reg = /a/
// 进行匹配校验
// 语法: reg.test(你想校验的字符串),返回校验的结果,如果有则返回true,否则返回false
let result = reg.test(str)
console.log(result)
</script>
总结
- 正则表达式使用分为几步?
- 定义正则表达式
- 检测查找是否匹配
2. 定界符
<script>
let str = prompt('请输入5位的号码')
// 添加一个正则,判断是否输入的是10086
// 默认只判断是否包含
// 我们往往需要严格的限制输入的内容的位数或者边界
// ^:以。。。开头
// $:以。。。结尾
let reg = /^10086$/
// 调用test方法实现校验
let result = reg.test(str)
console.log(result)
</script>
4. 占位符
<script>
// 占位符:说明这点需要 一个 指定(范围)的字符
// 有点像方法的形参,说明这里以后需要传入一个指定类型的值
let str = prompt('输值')
// 1. \d:代表一个数字: 0-9 --- 重点
// let reg = /^\d$/
// 2. \D:代表 一个 非数字
// let reg = /^\D$/
// 3. \w: 代表一个合法字符:js中合法字符有: a-z A-Z 0-9 _ ---- 重点
// let reg = /^\w$/
// 4.\W:代表一个非法字符串,除了合法就是非法的
// let reg = /\W/
// 5. \s: 代表一个空字符: 空格,换行,制表位..
// let reg = /^\s$/
// 6. \S: 代表一个非空字符:能够看见的字符就叫非空字符
// let reg = /^\S$/
// 7. .:代表一个任意字符
// let reg = /^.$/
// 8. []:代表一个指定的范围的某一个字符,范围可以是连续的也可以是具体的值 --- 重点
// let reg = /^[45678]$/
// -是范围连接符,代表一个连续的范围
// A-Z a-z 0-9
// let reg = /^[4-8]$/
// 范围指定只能从小到大,如果是从大到小就会报错
// let reg = /^[4-3]$/
// let reg = /^[0-z]$/ // 可以,但是中间还有其它的非法字符
let reg = /^[0-9A-Za-z_]$/
console.log(reg.test(str))
</script>
5. 修饰符
<script>
// 修饰符:起修饰作用的。它是来修饰前面的字符所出现的次数--量词
// 修饰符不能单独的存在,记住:先占位,后修饰
let str = prompt('输')
// 1.*:修饰前面的字符出现任意次
// let reg = /^1*$/
// 2. +:修饰前面的字符出现一次或多次
// let reg = /^1+$/
// 验证用户名: 要求至少一个合法字符
// let reg = /^\w+$/
// 3. ?:修改前面的字符出现 0次或1次
// 020-12345678 02012345678
// let reg = /^\d\d\d-?$/
// 3. {n}:修饰前面的字符出现n次
// let reg = /^\d{11}$/
// let reg = /^1[35789]\d{9}$/
// 4. {n,m}:修饰前面的字符最少出现n次,最多出现m次
// let reg = /^\w{6,16}$/
// let reg = /^\w{3,2}$/
// 5.{n,} :修饰前面的字符最少出现n次,最多没有限制
let reg = /^\w{3,}$/
console.log(reg.test(str))
</script>
6. 验证中文
<body>
<!-- 合法字符是指: a-z A-Z 0-9 _ -->
用户名:
<input
class="username"
type="text"
placeholder="请输入用户名,不能包含特殊符号"
/>
<br />
姓名: <input type="text" class="youname" /> <br />
密码: <input type="text" placeholder="请输入3到16位的密码" /> <br />
手机号:
<input type="text" class="phone" placeholder="请填写11位的手机号" /> <br />
邮箱:<input type="text" class="email" /> <br />
身份证号码:
<input type="text" class="userId" placeholder="请输入合法的身份证号" />
<br />
<button>提交</button>
<script>
let btn = document.querySelector('button')
let youname = document.querySelector('.youname')
btn.addEventListener('click', function() {
// 验证用户姓名,要求是中文
let name = youname.value
let reg = /^[\u4e00-\u9fa5]{2,6}$/
if (!reg.test(name)) {
alert('请输入2-6位的中文')
}
})
</script>
</body>
7. 检索(查找)符合规则的字符串:
exec() 方法 在一个指定字符串中执行一个搜索匹配
<script>
let email = 'wuhu0723@126.com'
// 需求:提取出 邮箱用户名
// exec:侧重于匹配成功之后的字符串提取
// 我们只需要将 你·想提取的字符串的正则表达式部分使用()包含
// 如果匹配成功:则返回一个数组,里面的索引0的值就是原始字符串,其它值就是你之前使用()包含的对应的源字符串部分
let reg = /^(\w+)[@]((\w+)[.]([a-zA-Z]{2,3}))$/
//
let obj = reg.exec(email)
console.log(obj)
</script>
如果匹配成功,exec() 方法返回一个数组,否则返回null
总结
1.正则表达式检测查找 test方法和exec方法有什么区别?
- test方法 用于判断是否有符合规则的字符串,返回的是布尔值 找到返回true,否则false
- exec方法用于检索(查找)符合规则的字符串,找到返回数组,否则为null
08-模板字符串的替换原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div class="box">
<ul>
<li>{{ name }}</li>
<li>{{ age }}</li>
<li>{{ gender }}</li>
</ul>
</div>
<script>
let obj = {
name: 'rose',
age: 19,
gender: '男'
}
let res = mytemplate('.box', obj)
document.querySelector('div').innerHTML = res
// 实现动态渲染:根据用户指定模板和数据,生成动态结构
// selector:选择器
// data:数据对象
// 渲染一个字符串模板
function mytemplate(selector, data) {
// 1.根据选择器获取模板内容
let htmlStr = document.querySelector(selector).innerHTML
console.log(htmlStr)
// 2.写一个正则表达式,提取你想要替换的部分,和对象的属性名称
let reg = /{{\s*(\w+)\s*}}/
// 3.进行字符串提取.一次只能匹配一个
let arr
while ((arr = reg.exec(htmlStr))) {
console.log(arr) //{{ name }} name
let a = arr[0] // {{ name }} 这就是我要替换的源字符串
let b = arr[1] // name :这就是我需要渲染的对象的属性名称
// 4.进行替换
// replace(你想替换的源字符串,替换为什么)
htmlStr = htmlStr.replace(arr[0], obj[b])
console.log(htmlStr)
}
return htmlStr
}
</script>
</body>
</html>
9. 正则替换
<script>
let str = `12 3123aa
bb12 312 312
31 23a 21
31b`
// 只能替换一个
// str = str.replace(' ', '')
// 可以替换所有满足条件的字符
// str = str.replaceAll(' ', '')
// g:全局匹配,正则从头匹配到最后
str = str.replace(/\s+/g, '')
console.log(str)
</script>
10. 改变优先级
<script>
let str = prompt('请输入一个值')
// 修饰符默认只是修饰前面的一个字符,我们可以通过()将多个字符包裹到一起,形成一个整体,那么修饰符就会修饰整个整体
let reg = /^a(bc)+$/
console.log(reg.test(str))
</script>
11-正则替换敏感词
<script>
let arr = ['a', 'b']
let str = `12 3123aa
bb12 312 312
31 23a 21
31b`
for (let i = 0; i < arr.length; i++) {
let reg = new RegExp(arr[i], 'g')
console.log(reg, typeof reg)
// g:全局匹配,正则从头匹配到最后
str = str.replace(reg, '*')
}
console.log(str)
</script>
元字符
普通字符:
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。 也就是说普通字符只能够匹配字符串中与它们相同的字符。
元字符(特殊字符)
- 一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
- 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm…..
- 但是换成元字符写法: [a-z]
参考文档:
MDN:developer.mozilla.org/zh-CN/docs/…
正则测试工具: tool.oschina.net/regex
为了方便记忆和学习,我们对众多的元字符进行了分类:
1. 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
- 正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
^:用什么开头
let reg = /^abc/;
let arr = ['abc'];
let re = reg.test(arr);
console.log(re);
$:用什么结尾
let reg = /abc$/;
let arr = ['abc'];
let re = reg.test(arr);
console.log(re);
如果 ^ 和 $ 在一起,表示必须是精确匹配。
let reg = /^abc$/;
let arr = ['abc'];
let re = reg.test(arr);
console.log(re);
// let reg = /^abc$/;
// console.log(reg.test(123));
// console.log(reg.test(123123));
// console.log(reg.test(12345));
2. 量词 (表示重复次数)
量词用来 设定某个模式出现的次数
注意: 逗号左右两侧千万不要出现空格
总结
- +表示重复至少 1 次
- ? 表示重复 0 次或1次
- *表示重复 0 次或多次
- {m, n} 表示复 m 到 n 次
- 字符类 (比如 \d 表示 0~9)
3. 字符类 (比如 \d 表示 0~9)
(1) [ ] 里面加上 - 连字符
- 使用连字符 - 表示一个范围
console.log(/^[a-z]$/.test('z'));//true
比如:
- [a-z] 表示 a 到 z 26个英文字母都可以
- [a-zA-Z] 表示大小写都可以
- [0-9] 表示 0~9 的数字都可以
认识下:腾讯QQ
console.log('腾讯QQ'+/^[1-9][0-9]{4,}$/.test('10000'));
(2)[ ] 里面加上 ^ 取反符号
比如:
- [^a-z] 匹配除了小写字母以外的字符
- 注意要写到中括号里面
(3).匹配除换行符之外的任何单个字符
总结
- 字符类
.(点)代表什么意思?
- 匹配除换行符之外的任何单个字符
- 字符类 [] 有若干代表什么意思?
- [abc] 匹配abc其中的任何单个字符
- [a-z] 匹配26个小写英文字母其中的任何单个字符
- [^a-z] 匹配除了26个小写英文字母之外的其他任何单个字符
用户名验证案例
需求:用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16位
分析:
①:首先准备好这种正则表达式模式 /^[a-zA-Z0-9-_]{6,16}$/
②:当表单失去焦点就开始验证.
③:如果符合正则规范, 则让后面的span标签添加 right 类.
④:如果不符合正则规范, 则让后面的span标签添加 wrong 类.
<input type="text" class="uname"> <span>请输入用户名</span>
<script>
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 中划线
var uname = document.querySelector('.uname');
var span = document.querySelector('span');
uname.onblur = function() {
if (reg.test(this.value)) {
console.log('正确的');
span.className = 'right';
span.innerHTML = '用户名格式输入正确';
} else {
console.log('错误的');
span.className = 'wrong';
span.innerHTML = '用户名格式输入不正确';
}
}
</script>
(4) 预定义:指的是某些常见模式的简写方式。
预定义类指的是某些常见模式的简写方式. 案例:验证座机号码
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;
表单验证案例
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
if (reg.test(this.value)) {
// console.log('正确的');
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
} else {
// console.log('不正确');
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请从新输入 ';
}
//QQ号验证: /^[1-9]\d{4,}$/;
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
function regexp(ele, reg) {
ele.onblur = function() {
if (reg.test(this.value)) {
// console.log('正确的');
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
} else {
// console.log('不正确');
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i> 格式不正确,请从新输入 ';
}
}
};
修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等 语法: /表达式/修饰符
- i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
- g 是单词 global 的缩写,匹配所有满足正则表达式的结果
replace 替换
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
语法:str = str.replace(/c/ig,'&&')字符串.replace(/正则表达式/,'替换的文本')
案例:屏蔽敏感词
<textarea cols="60" rows="10"></textarea>
<input type="button" value="点击发布留言">
<ul>
<!-- <li>内容</li>
<li>新的内容</li> -->
</ul>
<script type="text/javascript">
// 获取元素
let text = document.querySelector('textarea');
let btn = document.querySelector('input');
let ul = document.querySelector('ul');
// 监听事件
btn.addEventListener('click', function () {
// 创建li
let li = document.createElement('li');
// 放到ul
ul.appendChild(li);
// 获取内容
let txt = text.value;
// 屏蔽敏感字
txt = txt.replace(/早恋|ZL/gi, '**')
// 放到li里面
li.innerHTML = txt;
});