【学习笔记52】JavaScript正则表达式
2023-09-11 14:14:57 时间
一、什么是正则
- 规则表达式
- 我们来书写一段规则, 用于匹配一段字符串是否符合规则
1. 字面量的形式
const reg = /abc/;
console.log(reg);
2. 内置构造函数
const reg1 = new RegExp('abc');
console.log(reg1);
3. 两种创建正则表达式的区别
3.1 正常创建
const reg = /\w/ig;
const reg1 = new RegExp('abc', 'ig');
console.log(reg);
console.log(reg1);
3.2 区别
const reg = /\w/ig;
const reg1 = new RegExp('\w', 'ig');
console.log(reg);
console.log(reg1);
/**
* new RegExp('\w', 'ig')
*
* 会把'\w' 把w转化为以一个具有特殊含义的字符, 所以这一步没有什么意义
*
* 我们如果想要正则表达式为 \w \\w
*/
const reg = /\w/ig;
// const reg1 = new RegExp('\w', 'ig');
const reg1 = new RegExp('\\w', 'ig');
console.log(reg);
console.log(reg1);
二、正则的常用方法
1. 匹配:test
- 匹配字符串是否符合正则规则
- 符合 — true
- 不符合 — false
- 语法:正则.test(字符串)
// 要求字符串中包含abc
const reg = /abc/;
console.log(reg.test('qwertyui')); // false
console.log(reg.test('qwertyuiabc')); // true
console.log(reg.test('1234567890')); // false
2. 捕获
- 语法:
正则.exec(字符串)
2.1 没有捕获到: 直接返回一个 null
// 没有捕获到
const reg = /\d{3}/;
console.log(reg.exec('zxcvbnm'))s; // null
2.2 捕获到了
- 没有小括号也没g的情况, 永远捕获的都是下标0开始的第一个符合条件的
// 没有小括号, 也没有g
const reg = /\d{3}/;
console.log(reg.exec('z123xc456vb789nm000'));
console.log(reg.exec('z123xc456vb789nm000'));
console.log(reg.exec('z123xc456vb789nm000'));
- 没有小括号, 但是有修饰符g的情况
- 第一次捕获完成后, 第二次开始的时候, 会从第一次捕获结束的位置开始
- 第三次开始的时候, 会从第二次捕获结束的位置开始
- 当所有的匹配项都匹配完成后, 会返回一个null
- 当再次捕获的时候, 就从下标0重新开始
// 有修饰符g
const reg = /\d{3}/g;
console.log(reg.exec('z123xc456vb789nm000')); // 123
console.log(reg.exec('z123xc456vb789nm000')); // 456
console.log(reg.exec('z123xc456vb789nm000')); // 789
console.log(reg.exec('z123xc456vb789nm000')); // 000
console.log(reg.exec('z123xc456vb789nm000')); // null
console.log(reg.exec('z123xc456vb789nm000')); // 123
2.3 有小括号
- 下标0还是我们正常捕获到的内容
- 从下标1开始, 就是每个小括号捕获到的内容
// 有小括号
const reg = /(\d{3})(\d{3})(\d{4})(\d{4})(\d{4})/;
const str = '我的身份证号是:522632201911151016; 不信算了!!!';
console.log(reg.exec(str));
const reg1 = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}|\dX)/
const str1 = '我的身份证号是:52263220191115101X; 不信算了!!!';
console.log(reg1.exec(str1));
3. 课堂案例
- 将正则捕获到的值, 放置在数组中
const reg = /\d{3}/g;
const str = 'z123xc456vb789nm000';
var arr = [];
let newArr = reg.exec(str)
console.log(newArr);
while (newArr !== null) {
arr.push(newArr[0]);
newArr = reg.exec(str);
}
console.log(arr);
三、正则的元字符
正则表达式的符号由那些组成?
- 元字符:正则表达式的规则符号
- 修饰符:修饰整个正则表达式的符号
/**
* 元字符 - 普通元字符
*
* 1. \d 表示 一位(一个) 数字(0~9)
* 2. \D 表示 一位 非数字(除了0~9)
* 3. \w 表示 数字(0~9)字母(a-zA-Z)下划线(_) 其中的一个
* 4. \W 表示 除了数字(0~9)字母(a-zA-Z)下划线(_) 这些的某一个字符
* 5. \s 表示 一位空白字符
* 6. \S 表示 一位非空白字符
* 7. . 表示 一位非换行的任意字符
* 8. \ 表示转义符
* 把有意义的符号, 转为没有意义的文本
* 将没有意义的文本, 转为有意义的符号
*/
1. \d 表示字符串中, 至少包含一个数字(0~9)
const reg = /\d/;
console.log(reg.test('qwertyuiop')); // false
console.log(reg.test('!@#$%^&*')); // false
console.log(reg.test('1000')); // true
2. \D 表示字符串中,至少出现一个非数字的内容
const reg = /\D/;
console.log(reg.test('qwertyuiop')); // true
console.log(reg.test('!@#$%^&*')); // true
console.log(reg.test('1000')); // false
3. \w 表示字符串中, 至少包含一个数字(0~9)、字母(a-zA-Z)和下划线(_)其中的一个
const reg = /\w/;
console.log(reg.test('@#$%^&*')); // false
console.log(reg.test('@#$%_^&*')); // true
console.log(reg.test('y@#$%^&*')); // true
console.log(reg.test('6@#$%^&*')); // true
console.log(reg.test('abc_123')); // true
4. \W 表示字符串中, 至少出现一个 数字(0~9)、字母(a-zA-Z)和下划线(_)以外的字符
const reg = /\W/ ;
console.log(reg.test('@#$%^&*')) ; // true
console.log(reg.test('@#$%_^&*')); // true
console.log(reg.test('y@#$%^&*')); // true
console.log(reg.test('6@#$%^&*')); // true
console.log(reg.test('abc_123')) ; // false
5. \s 表示字符串中, 至少出现一个空白字符
const reg = /\s/;
console.log(reg.test('asd')); // false
console.log(reg.test('213')); // false
console.log(reg.test('#$%')); // false
console.log(reg.test('#$ %')); // true
6. \S 表示字符串, 至少出现一个非空白字符
const reg = /\S/;
console.log(reg.test('asd')); // true
console.log(reg.test('213')); // true
console.log(reg.test('#$%')); // true
console.log(reg.test('#$ %')); // true
console.log(reg.test(' ')); // false
7. . 表示字符串, 至少出现一个非换行的任意字符
const reg = /./ ;
console.log(reg.test('\n')); // false
console.log(reg.test('123\n')); // true
8. . 表示字符串中至少出现一个 小数点
const reg1 = /\./; //
console.log(reg1.test('100')); // false
console.log(reg1.test('1.00')); // true
四、正则的边界元字符
- ^ : 表示开头
- $ : 表示结尾
1. 表示字符串至少出现一个数字
// 表示字符串至少出现一个数字
const reg1 = /\d/;
console.log(reg1.test('abc123def')); // true
2. 表示字符串开头是一个数字
// 表示字符串开头是一个数字
const reg2 = /^\d/;
console.log(reg2.test('abc123def')); // false
console.log(reg2.test('123def')); // true
3. 表示字符串结尾是一个数字
// 表示字符串结尾是一个数字
const reg3 = /\d$/
console.log(reg3.test('abc123def')); // false
console.log(reg3.test('abc123')); // true
4. 表示字符串只能是一个数字
// 表示字符串只能是一个数字
const reg4 = /^\d$/
console.log(reg4.test('abc123def')); // false
console.log(reg4.test('123def')); // false
console.log(reg4.test('123')); // false
console.log(reg4.test('1')); // true
五、正则的限定元字符
- 表示前边一个符号出现多少次
/**
* 1. * 表示 0~正无穷次
* 2. + 表示 1~正无穷次
* 3. ? 表示 0~1次
* 4. {n} 表示 限定n次, 不能多也不能少
* 5. {n,} 表示 最少n次
* 6. {n,m} 表示 最少n次, 最多m次
*/
1. 字符串的数字只能出现0~正无穷次
// 这个字符串的数字只能出现0~正无穷次
const reg1 = /^\d*$/;
console.log(reg1.test('1')) ; // true
console.log(reg1.test('1a')); // false
2. 字符串的数字只能出现1~正无穷
// 这个字符串的数字只能出现1~正无穷
const reg2 = /^\d+$/;
console.log(reg2.test('100')) ; // true
console.log(reg2.test('qwer')) ; // false
console.log(reg2.test('999qwer')) ; // false
3. 字符串的数字只能出现0~1次
// 这个字符串的数字只能出现0~1次
const reg3 = /^\d?$/;
console.log(reg3.test('666')); // false
console.log(reg3.test('6')); // true
4. 字符串的数字只能出现2次
// 这个字符串的数字只能出现2次
const reg4 = /^\d{2}$/;
console.log(reg4.test('666')); // false
console.log(reg4.test('66')); // true
console.log(reg4.test('6')) ; // false
5. 字符串的数字最少出现2次
// 这个字符串的数字最少出现2次
const reg5 = /^\d{2,}$/
console.log(reg5.test('666')); // true
console.log(reg5.test('66')); // true
console.log(reg5.test('6')) ; // false
6. 字符串的数字最少出现2次,最多出现3次
// 这个字符串的数字最少出现2次,最多出现3次
const reg6 = /^\d{2,3}$/
console.log(reg6.test('6666')); // false
console.log(reg6.test('666')); // true
console.log(reg6.test('66')); // true
console.log(reg6.test('6')); // false
七、正则的特殊元字符
/**
* 1. ()
* + 含义1: 当成一个整体
* + 含义2: 单独捕获
*
* 2. |
* 或
* 字符为 或 左右两边的 都行
*
* 3. []
* 包含
* 注意: [abcd] 包含其中一个即可 [] 实际代表的就是 一位字符
*
* 4. [^]
* 非
* 注意: [^abcd] 只要不是他们四个中的一个即可 [^] 实际代表的就是一位字符
*
* 5. -
* 到(至)
* 通常与 包含 和 非 一起使用
* [0-9] 数字 0~9 中的一个 \d
* [^0-9] 不是数字 0~9 中的 一个 \D
* [a-z] 小写 字母a~z
* [A-Z] 大写 字母A~Z
*/
1. bc这个整体,一定出现2次
// 表示abc这个整体, 一定出现2次
const reg = /(abc){2}/;
console.log(reg.test('abcdef')); // false
console.log(reg.test('abcab')); // false
console.log(reg.test('abcabc')); // true
2. 字符串需要abc或者def出现两次
// 这个字符串需要abc或者def出现两次
const reg = /(abc|def){2}/;
console.log(reg.test('abcabc')); // true
console.log(reg.test('abcdef')); // true
console.log(reg.test('defabc')); // true
console.log(reg.test('defdef')); // true
3. 字符串只能是a-c其中的任意一个字符
// 这个字符串只能是a-c其中的任意一个字符
const reg = /^[a-c]$/;
console.log(reg.test('abc')); // false
console.log(reg.test('a')); // true
console.log(reg.test('b')); // true
console.log(reg.test('c')); // true
console.log(reg.test('@')); // false
4. 字符串只能是a-c之外的任意一个字符
// 这个字符串只能是a-c之外的任意一个字符
const reg = /^[^a-c]$/;
console.log(reg.test('abc')); // false
console.log(reg.test('a')); // false
console.log(reg.test('b')); // false
console.log(reg.test('c')); // false
console.log(reg.test('@')); // true
5. 练习:或的分界线在哪里
- 或的分界线是小括号或者正则的边界(正则的尽头)
// 这段正则什么含义?
const reg = /^abc|def$/;
/**
* 把这个正则分为两部分
*
* 1. ^abc
* 2. def$
*/
console.log(reg.test('abc12345678')); // true
console.log(reg.test('12345678def')); // true
console.log(reg.test('1234abcdef5678')) ; // false
// 这段正则什么含义?
const reg1 = /^ab(c|d)ef$/;
// ^a b (c或者d 都行) e f$
console.log(reg1.test('abcef')); // true
console.log(reg1.test('abdef')); // true
console.log(reg1.test('bdef')); // false
console.log(reg1.test('abde')); // false
八、正则的重复元字符
- 符号: \1 \2 … \9(代表第几个小括号的值)
/**
* /(abc|def)\1/
* 小括号内为 abc \1 这个位置也需要是 abc
* 小括号内为 def \1 这个位置也需要是 def
*/
1. 小括号内是什么,\1的位置就应该是什么
// 小括号内是什么 \1的位置就应该是什么
const reg = /^(abc|def)\1$/;
console.log(reg.test('abcdef')); // false
console.log(reg.test('abcabc')); // true
console.log(reg.test('defabc')); // false
console.log(reg.test('defdef')); // true
2. 小阔内的内容, 出现两次, 但是每次的值, 可以不同
// 小阔内的内容, 出现两次, 但是每次的值, 可以不同
const reg1 = /^(abc|def){2}$/;
console.log(reg1.test('abcdef')); // true
console.log(reg1.test('abcabc')); // true
console.log(reg1.test('defabc')); // true
console.log(reg1.test('defdef')); // true
const reg2 = /^<(p|span)><\/\1>$/;
console.log(reg2.test('<span></span>')); // true
console.log(reg2.test('<p></p>')); // true
console.log(reg2.test('<p></span>')); // false
九、正则的标识符(修饰符)
- 书写在正则外边,用于描述整个正则表达式
- i(忽略大小写)
- g(全局)
const reg = /^[a-c]$/;
console.log(reg.test('a')); // true
console.log(reg.test('A')); // false
// 忽略大小写
const reg1 = /^[a-c]$/i;
console.log(reg1.test('a')); // true
console.log(reg1.test('A')); // true
十、正则的两大特性
1. 懒惰
- 正常捕获字符串的时候, 每次都从下标0开始
- 解决方式: 给正则添加一个修饰符g
2. 贪婪
- 每次在捕获的时候, 会尽可能的多捕获一些东西
- 解决:在原有的修饰符后添加一个 ? 然后相当于开启非贪婪模式
- 贪婪: 能多拿就多拿
- 非贪婪: 能少拿就少拿
const str = '<div class="box" id="box1"><span></span></div>';
// 贪婪模式
const reg = /<div.*>/;
console.log(reg.exec(str));
const str = '<div class="box" id="box1"><span></span></div>';
// 非贪婪模式
const reg = /<div.*?>/;
console.log(reg.exec(str));
/**
* 贪婪限定符
* *
* +
* ?
* {n,}
* {n,m}
*
* 非贪婪限定符
* *?
* +?
* ??
* {n,}?
* {n,m}?
*/
相关文章
- JavaScript经典代码【二】【javascript判断用户点了鼠标左键还是右键】
- [Javascript] Broadcaster + Operator + Listener pattern -- 8. Pass a Done Symbol when an Async Function is Done
- [Javascript] Delegate JavaScript (ES6) generator iteration control
- [Javascript] What is JavaScript Function Currying?
- [Javascript] Hoisting in JavaScript
- [Javascript] IIFE
- javascript: addEventListener对事件冒泡和事件捕获的处理演示(chrome 108.0.5359.98)
- [Javascript Crocks] Recover from a Nothing with the `coalesce` Method
- javascript:每次只加载3个页面的幻灯(chrome 105.0.5195.125)
- javascript案例8——简易全选、全不选、反选
- Array_JavaScript
- 【华为OD机试 2023】 网上商城优惠活动 / 模拟商场优惠打折II(C++ Java Javascript Python)
- chromium-embedded-how-to-execute-a-javascript-callback-from-c
- JavaScript--Dom间接选择器
- Javascript 的数据是什么数据类型?
- JavaScript实现黏贴上传图片功能