外观
01_正则表达式
01_什么是正则表达式
01_背景
- 在日常开发中, 我们经常会遇到使用正则表达式的场景, 比如一些常见的表单校验, 会让你匹配用户输入的手机号 或者身份信息是否规范, 这就可以用正则表达式去匹配
- 正则作为一个用途比较广泛的技术, 理应被我们所掌握, 而不是每次都只有在需要用到的时候 临时去网上查找, 如果出了问题 你也找不到问题出在哪
02_什么是正则表达式
- 正则表达式是用于匹配 字符串中字符组合的模式; 许多语言都支持正则表达式, 在 JavaScript 中, 正则表达式也是对象
- 就是用来匹配字符串的规则
判断一个字符串中是否包含 某个字符 或者 某个字符串
- 找出字符串 'ooooooOooooooo' 中是否有大写字母 O
判断用户输入的手机号是否合法
02_基本语法
01_定义一个正则表达式
- const 变量名 = /表达式/
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.定义一个正则表达式
const reg = /前端/
</script>
</body>
</html>
02_test() 字符串内是否匹配
查看正则表达式 与 指定的字符串内 是否匹配
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义一个正则表达式
const reg = /前端/
// 1.匹配到就返回 true, 否则返回 false
const res = reg.test('学前端, 找黑马')
console.log(res) // true
</script>
</body>
</html>
03_exec() 字符串内是否存在
查找正则表达式 与 指定的字符串内 是否存在
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义一个正则表达式
const reg = /前端/
// 1.存在就返回数组, 否则返回 null
const res = reg.exec('学好前端, 找黑马')
console.log(res) // ['前端', index: 2, input: '学好前端, 找黑马', groups: undefined]
</script>
</body>
</html>
04_replace() 替换字符串
查看字符串内 与 指定的正则表达式是否匹配; 匹配的话, 替换字符串
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义一个正则表达式
const reg = /前端/
// 1.匹配到就替换字符串, 匹配不到就不替换, 只能替换第一个匹配到的
const str = '学前端, 找黑马, 前端就业前景好, 前端工资高'
const res = str.replace(reg, 'java')
console.log(res) // 学java, 找黑马, 前端就业前景好, 前端工资高
</script>
</body>
</html>
05_match ()
查看字符串内 与 指定的正则表达式是否存在; 存在的话, 就返回数组
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定义一个正则表达式
const reg = /前端/
// 1.存在就返回数组, 否则返回 null
const str = '学前端, 找黑马, 前端就业前景好, 前端工资高'
const res = str.match(reg)
console.log(res) // ['前端', index: 1, input: '学前端, 找黑马, 前端就业前景好, 前端工资高', groups: undefined]
</script>
</body>
</html>
03_修饰符
01_修饰符
修饰符约束正则执行的某些细节行为, 如是否区分大小写, 是否全局匹配
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// i: 忽略大小写
const reg = /a/i
console.log(reg.test('a')) // true
console.log(reg.test('abc')) // true
console.log(reg.test('ABC')) // true
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// g: 全局匹配
const reg = /java/g
const str = '学java, 找黑马, java工资高, java前景好'
console.log(str.replace(reg, '前端')) // 学前端, 找黑马, 前端工资高, 前端前景好
</script>
</body>
</html>
04_元字符
01_元字符介绍
01_普通字符
大多数的字符仅能够描述它们本身, 这些字符称作普通字符, 例如所有的字母和数字
02_元字符
是一些具有特殊含义的字符, 可以极大提高了灵活性和强大的匹配功能
- 比如: 匹配 26 个英文字母, 用普通字符表示 abcde...xyz, 但是用元字符表示的话, 只需要 [a-z]
02_边界符
01_单词边界
找出某句话中的某个单词, 例如: The cat scattered his food all over the room
- 想找到 cat 这个单词, 但是如果只是使用 /cat/ 这个正则, 就会同时匹配到 cat 和 scattered 这两处文本
- 这时候就可以用到单词边界 \b, 这个正则就只会匹配到单词 cat 而不会匹配到 scattered 了
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.单词边界 \b
const reg = /\bcat\b/g
const str = 'The cat scattered his food all over the room'
const res = str.replace(reg, 'dog')
console.log(res) // The dog scattered his food all over the room
</script>
</body>
</html>
02_字符串边界
如果 ^ 和 $ 在一起, 表示必须是精确匹配
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配以 a 开头的字符串 ^
const reg = /^a/
console.log(reg.test('a')) // true
console.log(reg.test('abc')) // true
console.log(reg.test('bcd')) // false
console.log(reg.test('Abc')) // false
</script>
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配以 c 结尾的字符串 $
const reg = /c$/
console.log(reg.test('abc')) // true
console.log(reg.test('bcd')) // false
</script>
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.精确匹配 a 字符串 ^ $
const reg = /^a$/
console.log(reg.test('a')) // true
console.log(reg.test('aaa')) // false
</script>
</script>
</body>
</html>
03_量词
01_量词
表示某个模式出现的次数
- 逗号两侧不能出现空格
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// *: 表示 0 次 或 更多次
const reg = /^a*$/
console.log(reg.test('')) // true
console.log(reg.test('a')) // true
console.log(reg.test('aaa')) // true
console.log(reg.test('b')) // false
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// +: 表示 1 次 或 更多次
const reg = /^a+$/
console.log(reg.test('a')) // true
console.log(reg.test('aaa')) // true
console.log(reg.test('')) // false
console.log(reg.test('b')) // false
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// ?: 表示 0 次 或 1 次
const reg = /^a?$/
console.log(reg.test('')) // true
console.log(reg.test('a')) // true
console.log(reg.test('aaa')) // false
console.log(reg.test('b')) // false
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// {n}: 表示只能有 n 次
const reg = /^a{3}$/
console.log(reg.test('')) // false
console.log(reg.test('a')) // false
console.log(reg.test('aaa')) // true
console.log(reg.test('aaaa')) // false
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// {n,}: 表示大于等于 n 次
const reg = /^a{2,}$/
console.log(reg.test('')) // false
console.log(reg.test('a')) // false
console.log(reg.test('aa')) // true
console.log(reg.test('aaa')) // true
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// {n,m}: n 到 m 次, 包括 n 和 m 次
const reg = /^a{2,4}$/
console.log(reg.test('')) // false
console.log(reg.test('a')) // false
console.log(reg.test('aa')) // true
console.log(reg.test('aaaa')) // true
console.log(reg.test('aaaaaaa')) // false
</script>
</body>
</html>
04_字符类
01_[] 匹配字符合集
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配 abc 中的任意一个 []
const reg = /[abc]/
console.log(reg.test('abc')) // true
console.log(reg.test('andy')) // true
console.log(reg.test('body')) // true
console.log(reg.test('cindy')) // true
console.log(reg.test('ddy')) // false
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.连字符 -
// const reg = /[a-z] // 匹配 a 到 z 的 26 个小写字母中的任意一个
// const reg = /[A-Z] // 匹配 A 到 Z 的 26 个大写字母中的任意一个
// const reg = /[0-9] // 匹配 0 到 9 的数字中的任意一个
// const reg = /[a-zA-Z0-9_]/ // 匹配 a 到 z 的 26 个小写字母, A 到 Z 的 26 个大写字母, 0 到 9 的数字, _下划线; 中的任意一个
</script>
</body>
</html>
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配非数字 ^
const reg = /[^0-9]/
console.log(reg.test('aaa')) // true
console.log(reg.test('1111')) // fasle
console.log(reg.test('aaa11')) // true
</script>
</body>
</html>
02_匹配的是除 换行符和空格 之外的任意字符 .
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配的是除 换行符和空格 之外的任意字符 .
const reg = /./
console.log(reg.test('1')) // true
console.log(reg.test('aaa')) // true
console.log(reg.test('')) // false
console.log(reg.test('\n')) // false
console.log(reg.test('\r')) // false
</script>
</body>
</html>
03_预定义
指的是某些常见模式的简写方式
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.预定义
const reg1 = /\d/ // \d ==> [0-9] 匹配 0 到 9 之间的任意一个数字
const reg2 = /\D/ // \D ==> [^0-9] 匹配非数字
</script>
</body>
</html>
05_分组 + 分支结构
01_分组
01_分组
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.分组 (), 匹配一个或多个 ab
const reg = /(ab)+/
console.log(reg.test('ab')) // true
console.log(reg.test('abab')) // true
</script>
</body>
</html>
02_分组捕获
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 将 2023-01-05 格式的日期替换成 01/05/2023
const date = '2023-01-05'
// 1.分组捕获 (\d{4}) (\d{2}) (\d{2}) 分别对应 $1 $2 $3 即年月日
const reg = /^(\d{4})-(\d{2})-(\d{2})$/
const res = date.replace(reg, '$2/$3/$1')
console.log(res) // 01/05/2023
</script>
</body>
</html>
02_分支结构
01_分支结构
分支结构类似逻辑操作中的 或操作, 表示匹配 规则1 或者 规则2
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.分支结构 |
const reg = /前端|java/
const str1 = '学前端找黑马'
const str2 = '学java找黑马'
const str3 = '学挖掘机找蓝翔'
console.log(reg.test(str1)) // true
console.log(reg.test(str2)) // true
console.log(reg.test(str3)) // false
</script>
</body>
</html>
06_综合案例
01_密码匹配 (6~16 位字母, 数字或者下划线)
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.密码匹配 (6~16 位字母, 数字或者下划线)
// const reg = /^[a-zA-Z0-9_]{6,16}$/
const reg = /^\w{6,16}$/
console.log(reg.test('000000')) // true
console.log(reg.test('hello2023')) // true
</script>
</body>
</html>
02_匹配 16 进制颜色值 (比如: #f0f0f0, #fff)
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配 16 进制颜色值 (比如: #f0f0f0, #fff)
const reg = /^#[0-9a-fA-F]{6}|[0-9a-fA-F]{3}$/
console.log(reg.test('#f0f0f0')) // true
console.log(reg.test('#fff')) // true
console.log(reg.test('#000000')) // true
console.log(reg.test('#ffffff')) // true
</script>
</body>
</html>
03_匹配 24 小时制的时间 (比如: 23:59, 08:29)
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.匹配 24 小时制的时间 (比如: 23:59, 08:29)
const reg = /^(([01][0-9])|(2[0-3])):[0-5][0-9]/
console.log(reg.test('23:59')) // true
console.log(reg.test('08:29')) // true
console.log(reg.test('00:00')) // true
console.log(reg.test('20:00')) // true
</script>
</body>
</html>
04_手机号码加密 15812345678 ==> 158****5678
html
<!-- /code/test.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1.手机号码加密 15812345678 ==> 158****5678
const str = '15812345678'
// 2.分组捕获 (1[3-9]\d) (\d{4}) 分别对应 $1 $2
const reg = /^(1[3-9]\d)\d{4}(\d{4})/
console.log(str.replace(reg, '$1****$2'))
</script>
</body>
</html>
07_常用正则的工具
01_VSCode 插件 any-rule
- F1: 支持一键生成常见的正则表达式