JavaScript之正则表达式
2023-07-07 本文已影响0人
h2coder
正则表达式
正则表达式(Regular Expression)是一种字符串匹配的模式(规则)
-
使用场景
- 例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
- 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等
-
正则基本使用分为两步
-
定义规则
- 其中 / / 是正则表达式字面量
- 正则表达式也是对象
const reg = /表达式/
- 使用正则
- test() 方法 用来查看正则表达式与指定的字符串是否匹配
- 如果正则表达式与指定的字符串匹配 ,返回true,否则false
const reg = /前端/;
// 目标字符串
const str = '前端,大前端,大大大前端';
// 使用正则
console.log(reg.test(str)); // true
- 基本使用
<!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>正则表达式的基本使用</title>
</head>
<body>
<script>
// 定义正则规则,两个/,不需要加引号,否则就变成字符串了
// const reg = /前端/;
// const reg = /后端/;
// 字符串
// const str = '前端,大前端,大大大前端';
// 使用正则
// console.log(reg.test(str));
/*
需求:检测字符是否存在
*/
const reg = /猪脚/;
// const reg = /沙县/;
const str = '今天天气真好,适合吃猪脚';
console.log(reg.test(str));
</script>
</body>
</html>
元字符
- 普通字符
- 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字
- 普通字符只能够匹配字符串中与它们相同的字符
- 比如,规定用户只能输入英文26个英文字母,普通字符的话 /[abcdefghijklmnopqrstuvwxyz]/
- 元字符(特殊字符)
- 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能
- 比如,规定用户只能输入英文26个英文字母,换成元字符写法: /[a-z]/
边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符,^和$。即定义位置规则,必须用什么开头,用什么结尾
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
- 如果 ^ 和 $ 在一起,表示必须是精确匹配
<!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>元字符之边界符</title>
</head>
<body>
<script>
/*
元字符之边界符
^ 表示匹配行首的文本(以谁开始)
& 表示匹配行尾的文本(以谁结束)
^$同时出现 表示精确匹配
*/
// 1. 匹配开头的位置 ^
const reg = /^web/
console.log(reg.test('web前端')) // true
console.log(reg.test('前端web')) // false
console.log(reg.test('前端web学习')) // false
console.log(reg.test('we')) // false,因为不完整
console.log('-------------------');
// 2. 匹配结束的位置 $
const reg1 = /web$/
console.log(reg1.test('web前端')) // false
console.log(reg1.test('前端web')) // true
console.log(reg1.test('前端web学习')) // false,因为必须以web结尾
console.log(reg1.test('we')) // false,因为不完整
console.log('-------------------');
// 3. 精确匹配 ^ $
const reg2 = /^web$/
console.log(reg2.test('web前端')) // false
console.log(reg2.test('前端web')) // false
console.log(reg2.test('前端web学习')) // false
console.log(reg2.test('we')) // false
console.log(reg2.test('web')) // true
console.log(reg2.test('webweb')) // false,没有精确匹配,要完全一样,只有3个字符串,就是web
</script>
</body>
</html>
量词
量词用来设定某个模式重复次数,即定义重复次数规则
量词 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
- 注意: 逗号左右两侧千万不要出现空格
<!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>元字符之量词</title>
</head>
<body>
<script>
/*
元字符之量词
* 重复零次或更多次
+ 重复一次或多次(至少一次)
? 重复零次或一次(要么没有,要么只出现一次)
{n} 重复n次
{n,} 重复n次或更多次(相当于 >= n)
{n,m} 重复n到m次(区间范围,n =< 重复次数 <= m)
*/
// 1. * 重复次数 >= 0 次
const reg1 = /^w*$/
console.log(reg1.test('')) // true,因为零次或多次都可以
console.log(reg1.test('w')) // true
console.log(reg1.test('ww')) // true
console.log('------------');
// 2. + 重复次数 >= 1 次
const reg2 = /^w+$/
console.log(reg2.test('')) // false,因为一次都没有
console.log(reg2.test('w')) // true
console.log(reg2.test('ww')) // true
console.log('------------');
// 3. ? 重复次数 0 || 1
const reg3 = /^w?$/
console.log(reg3.test('')) // true,因为可以是零次
console.log(reg3.test('w')) // true,因为可以是一次
console.log(reg3.test('ww')) // false,因为不可以一次以上
console.log('------------');
// 4. {n} 重复 n 次
const reg4 = /^w{3}$/
console.log(reg4.test('')) // false
console.log(reg4.test('w')) // false
console.log(reg4.test('ww')) // false
console.log(reg4.test('www')) // true
console.log(reg4.test('wwww')) // false,因为必须是3次,大于和小于3次都不行
console.log('------------');
// 5. {n,} 重复次数 >= n
const reg5 = /^w{2,}$/
console.log(reg5.test('')) // false
console.log(reg5.test('w')) // false
console.log(reg5.test('ww')) // true,因为可以等于2
console.log(reg5.test('www')) // true,因为可以大于等于2
console.log('------------');
// 6. {n,m} n =< 重复次数 <= m
const reg6 = /^w{2,4}$/
console.log(reg6.test('w')) // false,只能2到4次
console.log(reg6.test('ww')) // true,因为可以2次
console.log(reg6.test('www')) // true,因为可以3次
console.log(reg6.test('wwww')) // true,因为可以4次
console.log(reg6.test('wwwww')) // false,因为不可以超过4次
</script>
</body>
</html>
范围
表示字符的范围,定义的规则限定在某个范围,比如只能是英文字母,或者数字等等,用 [] 表示范围。即表示字符的范围
[abc] | 匹配包含的单个字符。也就是只有 a |
---|---|
[a-z] | 连字符。来指定字符范围。[a-z] 表示 a 到 z 26个英文字母 |
[^abc] | 取反符。[^a-z] 匹配除了小写字母以外的字符 |
- 使用连字符 - 表示一个范围
console.log(/^[a-z]$/.test('c'));// true
- 比如
- [a-z] 表示 a 到 z 26个英文字母都可以
- [a-zA-Z] 表示大小写都可以
- [0-9] 表示 0~9 的数字都可以
- 腾讯QQ号(QQ号从10000开始):^[1-9][0-9]{4,}$
<!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>元字符之范围</title>
</head>
<body>
<script>
/*
元字符之范围 []
[abc] 匹配包含的单个字符。也就是只有 a || b || c 这三个单字符返回true, 可以理解为多选1
[a-z] 连字符。来指定字符范围。[a-z] 表示 a 到 z 26个英文字母
[^abc] 取反符。[^a-z] 匹配除了小写字母以外的字符
*/
// 1. [abc] 匹配包含的单个字符(a、b、c,其中一个都行),多选1
const reg1 = /^[abc]$/
console.log(reg1.test('a')) // true
console.log(reg1.test('b')) // true
console.log(reg1.test('c')) // true
console.log(reg1.test('d')) // false,因为d没有在范围内
console.log(reg1.test('ab')) // false,因为只能单个字符,这里2个字符
console.log('-----------------');
// 2. [a-z] 连字符(a到z之间的字母都可以),单个
const reg2 = /^[a-z]$/
console.log(reg2.test('a')) // true
console.log(reg2.test('p')) // true
console.log(reg2.test('0')) // false,因为0是数字,不是因为字母
console.log(reg2.test('A')) // false,因为只能是小写字母,A是大写字母
console.log('-----------------');
// 想要包含小写字母,大写字母 ,数字
const reg3 = /^[a-zA-Z0-9]$/
console.log(reg3.test('B')) // true
console.log(reg3.test('b')) // true
console.log(reg3.test(9)) // true
console.log(reg3.test(',')) // false,不是小写字母、大写字母、数字
console.log('-----------------');
// 用户名可以输入英文字母,数字,可以加下划线,要求 6~16位
const reg4 = /^[a-zA-Z0-9_]{6,16}$/
console.log(reg4.test('abcd1')) // false,只有5位
console.log(reg4.test('abcd12')) // true,有6位,满足要求
console.log(reg4.test('ABcd12')) // true,有6位,满足要求
console.log(reg4.test('ABcd12_')) // true,因为下划线也符合规则,所以有6位
console.log('-----------------');
// 3. [^a-z],取反符(除了小写字母以外)
// 注意,小写字母取反,就是不能是小写字母,其他都可以!!!
const reg5 = /^[^a-z]$/
console.log(reg5.test('a')) // false,因为不能是小写字母
console.log(reg5.test('A')) // true
console.log(reg5.test(8)) // true
// 4. 限定只能是中文
const reg6 = /[\u4E00-\u9FA5\uF900-\uFA2D]/
console.log(reg6.test('A'));
console.log(reg6.test('中文歌'));
console.log(reg6.test('123'));
</script>
</body>
</html>
案例,验证用户名
<!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>验证用户名案例</title>
<style>
dt,
dd {
margin: 0;
position: relative;
}
dl {
display: flex;
width: 600px;
height: 30px;
line-height: 30px;
}
dl dt {
margin-right: 5px;
}
dl input {
width: 269px;
height: 28px;
padding-left: 5px;
border: 1px solid #ccc;
outline: none;
background: transparent;
line-height: 30px;
border-radius: 5px;
}
.tip {
display: none;
position: relative;
width: 220px;
height: 30px;
margin-left: 15px;
border: 1px solid #f59fb1;
color: #d93c3c;
text-align: center;
font-size: 14px;
background-color: #fff2f5;
border-radius: 5px;
}
.tip::before {
content: '';
position: absolute;
top: 50%;
left: -6px;
width: 10px;
height: 10px;
background-color: #fff2f5;
border-left: 1px solid #f59fb1;
border-bottom: 1px solid #f59fb1;
transform: translateY(-50%) rotate(45deg);
}
span {
position: absolute;
top: 9px;
right: 10px;
width: 15px;
height: 15px;
}
.right {
background: url(./images/right.png) no-repeat;
}
.wrong {
background: url(./images/error1.png) no-repeat;
}
</style>
</head>
<body>
<dl>
<dt>用户名:</dt>
<dd><input type="text" class="uname"><span></span></dd>
<dd class="tip">输入6~16位数字字母-_组成</dd>
</dl>
<script>
/*
需求:用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16 位
分析:
1、首先准备好这种正则表达式模式 /^[a-zA-Z0-9-_]{6,16}$/
2、当表单失去焦点就开始验证. ③:如果符合正则规范, 则让后面的span标签添加 right 类
3、如果不符合正则规范, 则让后面的span标签添加 wrong 类,同时显示提示框
*/
// 输入框
const uname = document.querySelector('.uname');
// 提示
const tip = document.querySelector('.tip');
// 提示
const span = uname.nextElementSibling;
// 用户名的正则表达式
const reg = /^[a-zA-Z0-9-_]{6,16}$/
// 监听输入框失去焦点
uname.addEventListener('blur', function (e) {
// 获取输入框内容
let inputText = uname.value;
// 验证通过
if (reg.test(inputText)) {
// 显示√图标
span.classList.remove('wrong');
span.classList.add('right');
// 隐藏提示
tip.style.display = 'none'
} else {
// 不通过,显示X图标
span.classList.remove('right');
span.classList.add('wrong');
// 显示提示
tip.style.display = 'block'
}
});
</script>
</body>
</html>
案例,用户名必须是中文
<!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>验证用户名案例-限制只能是中文</title>
<style>
dt,
dd {
margin: 0;
position: relative;
}
dl {
display: flex;
width: 600px;
height: 30px;
line-height: 30px;
}
dl dt {
margin-right: 5px;
}
dl input {
width: 269px;
height: 28px;
padding-left: 5px;
border: 1px solid #ccc;
outline: none;
background: transparent;
line-height: 30px;
border-radius: 5px;
}
.tip {
display: none;
position: relative;
width: 220px;
height: 30px;
margin-left: 15px;
border: 1px solid #f59fb1;
color: #d93c3c;
text-align: center;
font-size: 14px;
background-color: #fff2f5;
border-radius: 5px;
}
.tip::before {
content: '';
position: absolute;
top: 50%;
left: -6px;
width: 10px;
height: 10px;
background-color: #fff2f5;
border-left: 1px solid #f59fb1;
border-bottom: 1px solid #f59fb1;
transform: translateY(-50%) rotate(45deg);
}
span {
position: absolute;
top: 9px;
right: 10px;
width: 15px;
height: 15px;
}
.right {
background: url(./images/right.png) no-repeat;
}
.wrong {
background: url(./images/error1.png) no-repeat;
}
</style>
</head>
<body>
<dl>
<dt>用户名:</dt>
<dd><input type="text" class="uname"><span></span></dd>
<dd class="tip">输入2~8位中文</dd>
</dl>
<script>
/*
需求:用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16 位
分析:
1、首先准备好这种正则表达式模式 /^[a-zA-Z0-9-_]{6,16}$/
2、当表单失去焦点就开始验证. ③:如果符合正则规范, 则让后面的span标签添加 right 类
3、如果不符合正则规范, 则让后面的span标签添加 wrong 类,同时显示提示框
*/
// 输入框
const uname = document.querySelector('.uname');
// 提示
const tip = document.querySelector('.tip');
// 提示
const span = uname.nextElementSibling;
// 验证中文的正则表达式
const reg = /^[\u4e00-\u9fa5]{2,8}$/
// 监听输入框失去焦点
uname.addEventListener('blur', function (e) {
// 获取输入框内容
let inputText = uname.value;
// 验证通过
if (reg.test(inputText)) {
// 显示√图标
span.classList.remove('wrong');
span.classList.add('right');
// 隐藏提示
tip.style.display = 'none'
} else {
// 不通过,显示X图标
span.classList.remove('right');
span.classList.add('wrong');
// 显示提示
tip.style.display = 'block'
}
});
</script>
</body>
</html>
字符类
某些常见模式的简写方式,区分字母和数字
字符类 | 说明 |
---|---|
\d | 匹配0-9之间的任一数字,相当于[0-9] |
\D | 匹配0-9以外的字符,相当于[^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] |
\W | 除所有字母、数字和下划线以外的字符,相当于 [^A-Za-z0-9_] |
\s | 匹配空格 (包括换行符、制表符、空格符等),相等于[\t\r\nv\f] |
\S | 匹配非空格的字符,相当于 [\t\r\n\w\f] |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>05-3-元字符之字符类</title>
</head>
<body>
<script>
/*
提示:大写字母的话,就是小写字母的规则取反
\d:匹配0-9之间的任一数字,相当于[0-9]
\D:匹配0-9以外的字符,相当于[^0-9]
\w:匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
\W:除所有字母、数字和下划线以外的字符,相当于 [^A-Za-z0-9_]
\s:匹配空格 (包括换行符、制表符、空格符等),相等于[\t\r\nv\f]
\S:匹配非空格的字符,相当于 [\t\r\n\w\f]
*/
// 日期格式的正则表达式
const reg = /^\d{4}-\d{1,2}-\d{1,2}$/;
// 日期格式:2099-12-12
console.log(reg.test('2099-12-12'));
// 日期格式:2099-1-1
console.log(reg.test('2099-1-1'));
</script>
</body>
</html>
替换和修饰符
使用replace 替换方法,可以完成字符的替换
替换
- 语法
字符串.replace(/正则表达式/, '替换的文本');
修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
- 语法
/表达式/修饰符
- i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
- g 是单词 global 的缩写,匹配所有满足正则表达式的结果
console.log(/a/i.test('a'));// true
console.log(/a/i.test('A'));// true
- 基本使用
<!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>替换和修饰符</title>
</head>
<body>
<script>
/*
语法:/表达式/修饰符
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
g 是单词 global 的缩写,匹配所有满足正则表达式的结果
*/
// 替换和修饰符
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
// 1. 替换 replace 需求:把前端替换为 web
// const newStr = str.replace(/前端/, 'web');
// console.log(newStr);
// 2. 修饰符 g 全部替换
// const newStr = str.replace(/前端/g, 'web');
// console.log(newStr);
// 3. 忽略大小写的匹配
const str2 = 'CBA';
// 虽然字符串里面是大写c,正则是小写c,但也能匹配上,将C替换为N
console.log(str2.replace(/c/i, 'N'));
/*
需求
将 欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神
前端改为挖掘机
*/
const newStr = str.replace(/前端/g, '挖掘机');
console.log(newStr);
</script>
</body>
</html>
案例,隐藏手机号中间四位
<!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>隐藏手机号中间四位案例.</title>
<style>
.wrapper {
width: 840px;
height: 420px;
background: url(./images/bg01.jpg) no-repeat center / cover;
padding: 100px 250px;
box-sizing: border-box;
}
.wrapper strong {
font-size: 50px;
}
.wrapper span {
color: #b10e0d;
}
</style>
</head>
<body>
<div class="wrapper">
<strong>年会抽奖</strong>
<h1>获奖手机号:<span class="phone">???</span></h1>
</div>