# 正则表达式
# 什么是正则表达式 — 介绍
- 正则表达式 (Regular Expression) 是用于匹配字符串中字符组合的模式。在 JavaScript 中,正则表达式也是对象.
- 通常用来查找,替换那些符合正则表达式的文本,许多语言都支持正则表达式。
请在上图中找出 [戴帽子和眼镜的男人]
戴帽子,戴眼镜,男人 都是描述信息,通过这些信息能够在人群中查找到确定的某个人,那么这些用于查找的描述信息编写一个模式,对应到计算机中就是所谓的正则表达式。
- 正则表达式在 JavaScript 中的使用场景:
- 例如验证表单:用户名表单只能输入英文字母,数字或者下划线,昵称输入框中可以输入中文 (匹配)
- 比如用户名:
/^[a-z0-9_-]{3,16}$/
- 比如用户名:
- 过滤掉页面内容中的一些敏感词 (替换),或从字符串中获取我们想要的特定部分 (提取) 等。
# 总结
1 正则表达式是什么?
- 是用于匹配字符串中字符组合的模式.
2 正则表达式有什么作用?
- 表单验证 (匹配)
- 过滤敏感词 (替换)
- 字符串中提取我们想要的部分 (提取)
# 语法
我们想要查找是否有戴眼镜的人,怎么做呢?
- 定义规则:戴眼镜的
- 根据规则去查找:找到则返回
正则同样道理,我们分为两步:
- 定义规则
- 查找
比如:查找下面文本中是否包含字符串 "前端"
let str = 'IT培训,前端开发,web前端,软件测试,产品经理,前端' |
JavaScript 中定义正则表达式的语法有两种。
# 1 定义正则表达式语法:
const 变量名 = /表达式/ |
其中
/ /
是正则表达式字面量.比如:
const reg = /前端/ |
# 2 判断是否有包含规则的字符串
test() 方法,用来查看正则表达式与指定的字符串是否匹配
- 语法:
regObj.test(被检测的字符串) |
秒记 法则: 现有规则,再去检查
比如:
const str = 'IT培训,前端开发,web前端,软件测试,产品经理,前端' | |
// 正则表达式使用 | |
// 1. 定义规则 | |
const reg = /前端/ | |
// 2. 匹配 | |
console.log(reg.test(str)) |
- 如果正则表达式与指定的字符串匹配,返回 true,否则 false.
结果:
# 3 检索 (查找) 符合规则的字符串
exec () 方法 是一个指定字符串中执行一个搜索匹配
如果匹配成功,exec () 方法返回一个数组,否则返回 null
- 语法:
regObj.exec(被检测字符串) |
- 比如:
const str = 'IT培训,前端开发,web前端,软件测试,产品经理,前端' | |
// 正则表达式使用 | |
// 1. 定义规则 | |
const reg = /前端/ | |
// 2. 检索 返回的是一个数组 | |
console.log(reg.exec(str)) |
结果:
# 总结
1 正则表达式检测查找 test 方法和 exec 方法有什么区别?
- test 方法,用于判断是否有符合规则的字符串,返回的是布尔值,找到返回 true,否则 false
- exec 方法 用于检索 (查找) 符合规则的字符串,找到返回数组,否则为 null
# 元字符
普通字符 (麻烦):
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
也就是说普通字符只能够匹配字符串中与它们相同的字符。
元字符 (特殊字符 比较轻松):
是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
- 比如,规定用户输入英文 26 个英文字母,普通字符的话 abcdefghijklm....
- 但是换成元字符写法:[a-z] 就是 a 到 z 的 26 个英文字母
# 总结
什么是元字符以及它的好处是什么?
- 是一款具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能
- 比如英文 26 个英文字母,我们使用元字符 [a-z] 简介和灵活
# 为了方便记忆和学习,我们对众多的元字符进行了分类:
- 边界符 (表示位置,开始和结尾,必须用什么开头,用什么结尾)
- 量词 (表示重复次数)
- 字符类 (比如 \d 表示 0 ~ 9)
# 1 边界符
- 正则表达式中的边界符 (位置符) 用来提示字符所处的 位置,主要有两个字符.
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本 (以谁开始) |
$ | 表示匹配行尾的文本 (以谁结束) |
如果 ^
和 $
在一起同时使用,表示必须是精确匹配。
代码:
console.log("----------------") | |
// 元字符 | |
console.log("--------元字符--------") | |
console.log(/哈/.test('哈')) //true | |
console.log(/哈/.test('哈哈'))//true | |
console.log(/哈/.test('二哈'))//true | |
console.log("--------边界符--------") | |
// 边界符 | |
// ^ 以谁开始 以哈开始 | |
console.log("--------^ 以谁开始 以哈开始--------") | |
console.log(/^哈/.test('哈'))//true | |
console.log(/^哈/.test('哈哈'))//true | |
console.log(/^哈/.test('二哈'))//false | |
// $ 以谁结尾 以哈结尾 | |
console.log("--------$以谁结尾 以哈结尾--------") | |
console.log(/哈$/.test('哈'))//true | |
console.log(/哈$/.test('哈哈'))//true | |
console.log(/哈$/.test('哈二'))//false | |
// 以谁开始 以谁结尾 以哈开始 以哈结尾 | |
// ^$ 一起使用就是精确匹配 只有这种写法为 true 其余都是 false | |
console.log("--------精确匹配 (^$)--------") | |
console.log(/^哈$/.test('哈'))//true | |
//^$ 写法是精确匹配 要求里面就是一个 哈 两个哈 / 一个以上 就 false | |
console.log(/^哈$/.test('哈哈'))//false | |
console.log(/^哈$/.test('二哈二'))//false | |
console.log("----------------") |
效果:
# 2 量词
量词用来 设定某个模式出现的次数.
量词 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复 n 次 |
{n,} | 重复 n 次或更多次 |
{n,m} | 重复 n 到 m 次 |
注意:<font color=red> 逗号左右两侧千万不要出现空格 </font>.
代码:
console.log('-----------*-----------') | |
console.log(/^哈*$/.test('哈哈')) //true | |
console.log(/^哈*$/.test('')) //true | |
console.log(/^哈*$/.test('哈哈哈')) //true | |
// 精确匹配内容必须只能是 哈 不能出现其它的字符 | |
console.log(/^哈*$/.test('哈二哈')) //false | |
console.log(/^哈*$/.test('哈二哈很')) //false | |
console.log(/^哈*$/.test('很二哈')) //false | |
console.log('-----------+-----------') | |
console.log(/^哈+$/.test('哈')) //true | |
console.log(/^哈+$/.test('哈哈')) //true | |
console.log(/^哈+$/.test('')) //false | |
console.log(/^哈+$/.test('哈哈二')) //false | |
console.log(/^哈+$/.test('哈二哈')) //false | |
console.log(/^哈+$/.test('二哈哈')) //false | |
console.log('-----------?-----------') | |
console.log(/^哈?$/.test('哈')) //true | |
console.log(/^哈?$/.test('')) //true | |
console.log(/^哈?$/.test('哈哈')) //false | |
console.log(/^哈?$/.test('哈哈二')) //false | |
console.log(/^哈?$/.test('二哈哈')) //false | |
console.log(/^哈?$/.test('二哈')) //false | |
console.log('-----------{n}-----------') | |
console.log(/^哈{3}$/.test('哈')) //false | |
console.log(/^哈{3}$/.test('哈哈')) //false | |
console.log(/^哈{3}$/.test('哈哈哈')) //true | |
console.log(/^哈{3}$/.test('哈哈哈哈')) //false | |
console.log('-----------{n,}-----------') | |
console.log(/^哈{3,}$/.test('哈')) //false | |
console.log(/^哈{3,}$/.test('哈哈')) //false | |
console.log(/^哈{3,}$/.test('哈哈哈')) //true | |
console.log(/^哈{3,}$/.test('哈哈哈哈')) //true | |
console.log(/^哈{3,}$/.test('哈哈哈哈哈')) //true | |
console.log('-----------{n,m}-----------') | |
//3 到 4 之间都是 true 其余都是 false (3,4 之间不要加空格 否则出错) | |
console.log(/^哈{3,4}$/.test('哈')) //false | |
console.log(/^哈{3,4}$/.test('哈哈')) //false | |
console.log(/^哈{3,4}$/.test('哈哈哈')) //true | |
console.log(/^哈{3,4}$/.test('哈哈哈哈')) //true | |
console.log(/^哈{3,4}$/.test('哈哈哈哈哈')) //false |
结果:
# 总结
+
表示重复至少 1 次或更多次 等价于 {1,}
?
表示重复 0 次或 1 次 等价于 {0,1}
*
表示重复 0 次或多次 等价于 {0,}
{n,m}
表示重复 n 到 m 次
所以建议 使用 {} 形式书写 量词 比较方便 且 统一
# 3 字符类
[ ]
匹配字符集合
- 后面的字符串只要包含
abc
中任意一个字符,都返回 true。
// 只要括号里面的任意字符出现都返回 true | |
console.log(/[abc]/.test('andy')) //true | |
console.log(/[abc]/.test('bady')) //true | |
console.log(/[abc]/.test('cry')) //true | |
console.log(/[abc]/.test('die')) //false |
/^[abc]$/
匹配字符 ^$
在一起就是精确匹配 只选 abc 其中一个 出现多个为 false
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]$/.test('abc')) //false | |
console.log(/^[a-zA-Z0-9-_]$/.test('a')) //true | |
console.log(/^[a-zA-Z0-9-_]$/.test('A')) //true | |
console.log(/^[a-zA-Z0-9-_]$/.test('_')) //true | |
console.log(/^[a-zA-Z0-9-_]$/.test('aA')) //false | |
console.log(/^[a-zA-Z0-9-_]$/.test('aA_')) //false |
可以配合量词使用就可以规定 [ ]
中包含的 字符出现 多少次了
console.log(/^[abc]$/.test('a')) //true | |
console.log(/^[abc]$/.test('b')) //true | |
console.log(/^[abc]$/.test('c')) //true | |
console.log(/^[abc]{2}$/.test('ab')) //true | |
console.log(/^[abc]{1,3}$/.test('abc')) //true | |
console.log(/^[a-zA-Z0-9-_]{6,16}$/.test('aabbcAB12__')) //true | |
console.log(/^[a-zA-Z0-9-_]{6,16}$/.test('aabbcAB12__@')) //false |
[ ]
里面加上 -
连字符.
- 使用连字符
-
表示一个范围.
console.log(/^[a-z]$/.test('c')) // true |
- 比如:
[a-z]
表示 a 到 z,26 个英文字母 其中一个都可以[a-zA-Z]
表示大小写都可以[0-9]
表示 0~9 的数字都可以
- 认识下:
- 第一位是
1~9
第二位是0~9
四位或者更多位 量词重复的是它傍边的字符类
QQ号: ^[1-9][0-9]{4,}$ (QQ号从10000开始) |
[ ]
里面加上 ^
取反符号
- 比如:
[^a-z]
匹配除了小写字母以外的字符- 注意要写到中括号里面,写在
/[^ ]/
中的^
就是取反的意思,写在/^[]/
中的^
就是以什么开头的意思。
console.log(/[^abc]$/.test('a')) //false |
.
匹配除换行符之外的任何字符
- 比如:
- 可以用来避免用户输入换行
- 除了换行符其它字符都为 true
console.log(/./.test('\n')) //false |
# 3.1 预定义
预定义:指的是某些常见的简写方式.
预定类 | 说明 |
---|---|
\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] |
日期格式:^\d{4}-\d{1,2}-\d{1,2}$ |
# 用户表单验证案例
代码:
html
<body> | |
<input type="text"> | |
<span></span> | |
<script src="./js/验证用户名案例.js"></script> | |
</body> |
css
<style> | |
span { | |
display: block; | |
width: 250px; | |
height: 30px; | |
line-height: 30px; | |
padding-left: 15px; | |
} | |
.error { | |
margin: 3px; | |
color: red; | |
background: url(./images/error1.png) no-repeat left center; | |
} | |
.right { | |
margin: 3px; | |
color: green; | |
background: url(./images/right.png) no-repeat left center; | |
} | |
</style> |
js
// 创建正则表达式 | |
const reg = /^[a-zA-Z0-9-_]{3,}$/ | |
// 获取元素对象 | |
const inputText = document.querySelector('input[type="text"]') | |
// 获取上面的元素的兄弟标签对象 | |
const span = inputText.nextElementSibling | |
// 绑定 离焦事件 | |
inputText.addEventListener('blur', function () { | |
// 判断规则 | |
if (reg.test(this.value)) { | |
span.innerHTML = '输入正确' | |
span.className = 'right' | |
} | |
else { | |
span.innerHTML = '输入错误' | |
span.className = 'error' | |
} | |
}) |
# 4 修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写,是否支持多行匹配等
/表达式/修饰符 |
- i 是单词 ignore (翻译:忽略) 的缩写,正则匹配时字母不区分大小写.
- g 是单词 global (翻译:全局) 的缩写,匹配所有满足正则表达式的结果.
- i 与 g 可以组合使用 i 不区分大小写,g 全局查找。
- 比如 如下
console.log(/a/i.test('a')) //true | |
console.log(/a/i.test('A')) //true |
代码:
console.log(/^java$/.test('java'))//true | |
console.log(/java/i.test('Java'))//true | |
console.log(/^java$/i.test('JAVA'))//true | |
console.log(/^java$/.test('java'))//true | |
console.log(/^java$/g.test('JAVA'))//false | |
console.log(/java/g.test('Java'))//false |
结果:
# 4.1 替换 replace 替换
语法:
字符串.replace(/正则表达式/,'替换的文本') |
代码:
- 默认只会查找出一个
const str = 'java是一门编程语言,记住是JAVA' | |
//i 不区分大小写,g 全局查找 可以组合使用 不区分大小查找全部匹配的字符 | |
const result = str.replace(/java/i,'前端') | |
console.log(result) |
效果:
- 使用 i 不区分大小写,g 全局查找 组合
const str = 'java是一门编程语言,记住是JAVA' | |
//i 不区分大小写,g 全局查找 可以组合使用 不区分大小查找全部匹配的字符 | |
const result = str.replace(/java/ig,'前端') | |
console.log(result) |
效果:
# 4.2 使用 | 运算符
- 同时满足判断的。
const str = 'java是一门编程语言,记住是JAVA' | |
// 不使用 i 区分大小写 可以使用 | 运算符 来判断是否满足匹配条件 | |
const result = str.replace(/java|JAVA/g,'前端') | |
console.log(result) |
# 综合案例 — 注册页面
需求 1:
发送验证码
用户点击之后,显示 05 秒后重新获取
时间到了,自动改为 重新获取
需求 2:
用户名验证 (注意封装函数 verifyxxx),失去焦点触发这个函数
正则 /^[a-zA-Z0-9_]{6,10}$/
如果不符合要求,则出现提示信息,并 return false 中断程序
否则 则返回 return true
之所以返回 布尔值,是为了 最后的提交按钮做准备
监听使用 change
事件,当鼠标离开了标签,并且表单值发生了变化时触发事件,不要使用 blue
离焦事件,那样用户并没有输入任何东西只是点了一下又点了其它位置就会触发事件很浪费资源的。