认识正则表达式 - Regular Expression
-
目的: 验证字符串是否符合规则
-
是一个 复杂数据类型
正则表达式的创建
1. 字面量方式创建
=> 语法:
var reg = /abcd/
2. 内置构造函数创建
=> 语法:
var reg = new RegExp('abcd')
两种创建方式的区别
- 欠着
正则表达式的常用方法
1. 匹配
-
目的: 检测对还是不对
-
语法: 正则表达式.test(字符串)
-
返回值: 一个布尔值
=> 如果字符串满足正则表达式规则, 那么返回 true
=> 如果字符串不满足正则表达式规则, 那么返回 false
2. 捕获
-
目的: 从原始字符串中截取出符合正则表达式规则的部分字符串片段
-
欠着
正则表达式的组成
-
文本内容
-
元字符
=> 在正则表达式内用一个符号来表示一类内容
- 标识符
元字符
-
\d 表示 一位 数字
-
\D 表示 一位 非数字
-
\s 表示 一位 空白内容(空格, 缩进)
-
\S 表示 一位 非空白内容
-
\w 表示 一位 数字字母下划线任意内容
-
\W 表示 一位 非数字字母下划线的任意内容
-
. 表示 一位 非换行的任意内容
-
\ 表示 转义符
元字符 - 边界元字符
1. ^ 表示字符串开始(开头)
2. $ 表示字符串结束(结尾)
注意: 当 ^ 和 $ 一起使用的时候, 表示 从开始到结束
=> 没有 ^ 和 $ 叫做 包含
=> 有 ^ 和 $ 叫做 只能
元字符 - 限定元字符
-
概念: 一个限定符只能修饰前面一个符号
-
* 表示重复出现 0 ~ 正无穷 次
-
+ 表示重复出现 1 ~ 正无穷 次
-
? 表示重复出现 0 ~ 1 次
-
{n} 表示重复出现 n 次
-
{n,} 表示重复出现 n ~ 正无穷 次
-
{n,m} 表示重复出现 n ~ m 次
-
元字符 - 特殊元字符
1. ()
=> 含义1: 一个整体
=> 含义2: 单独捕获(欠着)
2. |
=> 或者
=> 一般和 () 连用
=> 只有 () 和 ^ 和 $ 能区分或的边界
3. []
=> 注意: 一个 [] 只占一位字符位置
=> 书写在 [] 内的任意一个字符都行
4. [^]
=> 注意: 一个 [^] 只占一位字符位置
=> 书写在 [^] 内的任意一个字符都不行
5. 中划线(-)
=> 表示 至 或者 到
=> 一般和 [] 连用
=> 注意: 必须保证 ASCII 码是连续的
=> 特殊: \u4e00-\u9fa5 所有中文
元字符 - 重复元字符
- \1 \2 \3 \4 \5 \6 \7 \8 \9
-
重复出现
-
需要第 n 个 () 出现的内容一模一样
-
注意: 不是重复几次,
是重复第几个小括号
问题: 如何区分第几个小括号 ?
- 在正则内按照 小括号开始 数数
元字符 - 预查元字符
1. 正向肯定预查
- (?=内容)真实正则内容
2. 正向否定预查
- (?!内容)真实正则内容
3. 负向肯定预查
- (?<=内容)真实正则内容
4. 负向否定预查
- (?!=内容)真实正则内容
标识符
-
书写在正则外面, 正则的后面
-
用来修饰整个正则表达式使用的
1. g 全局标识符 globle
- 欠着
2. i 忽略大小写 ignore
捕获
-
语法: 正则.exec(字符串)
-
返回值:
1. 原始字符串内没有符合正则要求的字符串片段
=> 返回值就是 null
2. 原始字符串内有符合正则要求的字符串片段
=> 返回值是一个数组数据类型, [0] 位置就是从字符串内捕获出来的内容
2-1. 正则没有 () 没有全局标识符 g
=> 返回值数组只有 [0] 数据
=> 不管你捕获多少次, 正则都是从原始字符串开始位置进行检索
2-2. 正则有 ()
=> 返回值数组 [0] 依旧是捕获出来的完整字符串片段
=> 从 [1] 开始依次是每一个小括号的单独内容捕获
2-3. 正则有 g
=> 返回的数组 [0] 依旧是捕获出来的完整字符串片段
=> 但是从第二次开始, 会从第一次捕获结束位置开始检索
=> 以此类推, 直到找不到了为止, 返回 null
=> 再下一次又从字符串开始位置进行检索
匹配但不捕获 (?😃
正则的两大特性
1. 懒惰性
=> 当你捕获内容的时候, 每一次都会默认从字符串的开头开始检索
=> 解决方案: 加一个全局标识符 g
2. 贪婪性
=> 贪婪匹配 能拿多少拿多少 尽可能多的捕获
=> 非贪婪匹配 能拿多少拿多少 尽可能少的捕获
=> 解决方案: 使用非贪婪限定符
贪婪匹配 指的都是 限定符
+ 贪婪限定符
=> *
=> +
=> ?
=> {n,}
=> {n,m}
+ 非贪婪限定符
=> *?
=> +?
=> ??
=> {n,}?
=> {n,m}?
创建方式的区别
1. 书写标识符的区别
=> 字面量: 直接书写在正则的后面
const reg = /abcd/gi
=> 内置构造函数: 以第二个参数的形式书写
const reg = new RegExp('abcd', 'gi')
2. 拼接变量的能力
=> 字面量方式不能进行变量拼接的
=> 内置构造函数可以拼接
-> 因为内置构造函数的第一个参数是一个字符串类型数据
3. 书写基本元字符
=> 字面量: /\s\d\w/
=> 内置构造函数内:
new RegExp('\\s\\d\\w')
字符串转义
-
在字符串内, \ 也是表示转义符
-
在字符串内书写 \s 这个内容, 相当于把没有意义的 s 文本转换成有意义的符号
=> 但是字符串内没有 \s 这个符号规则
=> 字符串就会默认把它解析为 s 文本
- 在你使用内置构造函数方式创建正则表达式的时候
=> 第一个参数是以字符串的形式书写正则内容
=> 当你在字符串内书写 ‘\s’ 的时候, 因为字符串规则, 会把他解析为 ‘s’
=> 给到正则的内容就是 ‘s’
=> 组装出来的就是 /s/
- 在你使用内置构造函数方式创建正则表达式的时候
=> 第一个参数是以字符串的形式书写正则内容
=> 当你在字符串内书写 ‘[\s](file://s)’ 的时候, 因为字符串规则, 第一个 \ 是把 第二个 \ 转义了
=> 就会在字符串内留下一个 斜线 和 s 文本
=> 当你把这个内容当做第一个参数写入的时候
=> 出来的正则就是 /\s/
字符串常用方法
1. replace()
=> 语法:
-> 字符串.replace(换下字符, 换上字符)
-> 字符串.replace(正则表达式, 换上字符)
=> 返回值: 替换好的字符串
-> 当你传递的是正则表达式, 并且带有 g 标识符的时候, 会全部替换
2. search()
=> 语法:
-> 字符串.search(字符串片段)
-> 字符串.search(正则表达式)
=> 返回值:
-> 如果有该字符串片段, 就是该字符串片段的开始索引位置
-> 如果没有该字符串片段, 就是 -1
3. match()
=> 语法:
-> 字符串.match(字符串片段)
-> 字符串.match(正则表达式)
=> 返回值:
-> 当你参数传递字符串片段, 或者没有 g 的正则表达式的时候, 和 exec 一模一样
-> 当你参数传递正则表达式, 并且有全局标识符 g 的时候, 返回值是一个数组, 里面是捕获到的所有内容
小练习
1. 用户名正则验证
- 要求: 只能包含 数字字母下划线 \w
不能以 下划线 开头 [0-9a-zA-Z]
共 6 ~ 12 位 {6,12}
const reg = /^[0-9a-zA-Z]\w{5,11}$/
2. 大陆手机号验证
- 要求:
可以有 +86 可以没有 (+86)? ?(133|135|188)\d{8}
+86 后面可以有一个空格 可以没有
手机号号段只要 133 135 188 开头
const reg = /^(\+86)? ?(133|135|188)\d{8}$/
3. 基本邮箱验证
- 要求:
@以前就是 用户名要求/^[0-9a-zA-Z]\w{5,11}$/
完全匹配 @ @
邮箱名称 qq 163 sina (qq|163|sina)
后缀只能是 com cn (com|cn)
const reg = /^[0-9a-zA-Z]\w{5,11}@(qq|163|sina)\.(com|cn)$/
4. 验证数字
- 要求:
=> 验证 0 ~ 255 的数字
- 分类:
=> 一位数 \d
=> 两位数 \d{2}
=> 三位数
-> 1 开头的三位数 1\d{2}
-> 2 开头的三位数
-
20 21 22 23 24 开头的三位数 2[0-4]\d
-
25 开头的三位数 25[0-5]
const reg = /^(\d|\d{2}|1\d{2}|2[0-4]\d|25[0-5])$/
const reg = /^(1?\d{1,2}|2[0-4]\d|25[0-5])$/
密码强度验证
问题1: 什么时候触发效果 ?
=> 随着输入随着验证
=> input 表单输入事件
问题2: 在哪一个标签身上触发效果 ?
=> input 标签
约定:
-
密码只能有 数字 字母 符号(@#!) 组成
-
包含任意一种, 就是 弱
-
包含任意两种, 就是 中
-
三种都包含, 就是 强
解决:
-
书写三个正则, 分别去验证用户输入的密码
-
通过一个, level ++
函数节流 和 函数防抖
- 函数节流: 节流阀, 开关
=> 在单位时间内只能触发一次内容
=> 从开始的时候, 就固定了结束时间
- 函数防抖:
=> 在单位时间内只能触发一次内容
=> 在开始以后, 当第二次开始的时候, 从新开始计时
表单验证
分析:
- 用户名
=> 表单 .username
=> 正则 用户名的正则
=> 错误提示 .username 后一个兄弟元素 span
=> 内容 .username 标签的 value
- 密码
=> 表单 .password
=> 正则 密码的正则
=> 错误提示 .password 后一个兄弟元素 span
=> 内容 .password 标签的 value
- 手机号
=> 表单 .phone
=> 正则 手机号的正则
=> 错误提示 .phone 后一个兄弟元素 span
=> 内容 .phone 标签的 value
- 只要我能给每一个 标签元素 加一个特殊标识, 就可以区分了
=> 利用 对象数据类型 存储正则表达式
=> 因为对象有 key 和 value
-> 让 key 和 标签的标识一致
-> 让 value 设置为正则表达式