文章目录
- 一、结构
- 1、匹配模式
- 2、字符组
- 3、量词
- 4、贪婪匹配和惰性匹配
- 5、多选分支
- 6、匹配模式关键词
- 二、位置
- 1、位置锚点
- 三、括号分组
- 1、分组
- 2、分支结构
- 3、引用分组
- 4、括号嵌套
- 四、回溯模式
- 1、回溯匹配
正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配字符串中的字符组合模式。在JavaScript中,正则表达式是一个对象,可以用于文本搜索和文本替换等操作。例如,检查字符串是否包含某个特定单词、验证用户输入的电话号码或电子邮件地址是否符合特定格式,或者从字符串中提取特定部分的内容。
一、结构
1、匹配模式
精确匹配应用比较局限,匹配数据比较少;模糊匹配结果可能性更多,能够满足更多场景
var regex = /hello/; // 精确匹配
regex = /^hello$/; // 精确匹配 + 完全匹配
regex = /hel{2}o/; // 模糊匹配 + 横向模糊(重复)
regex = /hel[lk]o/; // 模糊匹配 + 纵向模糊(该位置有多种可能)([lk]只占据一个位置)
console.log( regex.test("hello") );
2、字符组
字符组归纳了一连串的字符或者枚举值
// 正向字符组
12345可以表示成[1-5],该规范默认会被识别成字符组([-15]就不会被识别成字符组)
bcdefg可以表示成[b-g]
// 取反字符组
[^1-5]表示除了12345以外的字符
// 字符组简写
数字:\d 表示 [0-9];\D 表示 [^0-9]
单词(数字、字母、下划线):\w 表示 [a-zA-Z0-9_];\W 表示 [^a-zA-Z0-9_]
空白符(空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符):
\s 表示 [ \t\v\n\r\f];\S 表示 [^ \t\v\n\r\f]; // 注意空格
. 表示 任意字符
3、量词
假设匹配数量是num
{m} 表示 num = m
{m,} 表示 m <= num
{m, n} 表示 m <= num <= m
? 表示 0 <= num <= 1
+ 表示 1 <= num
* 表示 0 <= num
4、贪婪匹配和惰性匹配
- 默认贪婪匹配,量词后加?表示惰性匹配
- {m, n} + 贪婪匹配 === n
- {m, n}? + 惰性匹配 === m
var regex = /\d{2,5}/; // 12345
regex = /\d{2,5}?/; // 12
const string = "123456";
console.log(string.match(regex) );
5、多选分支
var regex = /red|color/g;
var string = "red yellow color"; // 示范值 [red, color]
string = "redcolor"; // red 匹配到了不会再选择领一个分支;分支也是默认惰性
console.log(string.match(regex) );
6、匹配模式关键词
g 表示 全局匹配,类似于贪婪匹配,匹配到一个满足条件的,不会停止,继续往下匹配
i 表示 忽略大小写
m 表示 多行,针对有\n换行符的字符串
二、位置
1、位置锚点
^ 表示 匹配开头,在多行匹配中匹配行开头
$ 表示 匹配结尾,在多行匹配中匹配行结尾
\b 表示 单词边界(单词左右两边和非单词的位置)
\B 表示 非单词边界(单词内部的字符之间的位置)
(?=key) 表示 key的一个子模式,表示key前面的那个位置
(?!key) 表示 key的一个子模式,表示不是key前面的那个位置
(?<=key) 表示 key的一个子模式,表示key后面的那个位置
(?<!key) 表示 key的一个子模式,表示不是key后面的那个位置
案例
// 空格匹配
console.log("hello".replace(/^|$/g, '#')); // #hello#
// 多行匹配
console.log("hello\nworld".replace(/^|$/gm, '#')); // #hello##world# m表示多行
// 单词边界
"world+".replace(/\b/g, '#') // #world#+ 注意头部和尾部和单词之间也算一个边界
// o前面的位置
"world+".replace(/(?=o)/g, '#') // w#orld+
// o后面的位置
"world+".replace(/(?<=o)/g, '#') // wo#rld+
三、括号分组
1、分组
字符的集合
// 固定字符串12的组合,对他们整体的子模式
console.log("12 123".match(/(12)+/g)) // 12 12
2、分支结构
该位置可选字符
/1(1|2)/g.test("12") // true
"121213".match(/1(1|2)/g) // [12, 12]
"121213".match(/1(1|2)+/g) // [1212] +号会让他变成贪婪匹配
3、引用分组
分组变量
// 正则中的分组引用 === \index 如\1, \2
"1231213".match(/(12)\d\1/g) // 12312 \1 表示分组变量 (12)
// 替换变量 $ + index
"12123".replace(/(12)(123)/g, "$2$1") // $1 表示分组变量 (12) $2 表示分组变量 (123)
// 分组全部替换
// $1 === 123; $2 === 12
// str被reg匹配为123 12 123 12,剩余字符串为‘’,直接替换
str = '123 12 123 12'
reg = /(123) (12) \1 \2/g
str.replace(reg, '$2-$1')
// return '12-123'
// 分组部分替换
// str被reg匹配为12 123,剩余字符串为'124 {regStr} 12'
// 12-123替换regStr,最终为'124 12-123 12'
str = '124 12 123 12'
reg = /(123)?(12) \1/g
str.replace(reg, '$2-$1')
// return '124 12-123 12'
4、括号嵌套
// 从左到右读取,碰到括号进入括号,再从左到右读取
"123".replace(/(\d(\d(\d)))/, "$1-$2-$3") // 123-12-3
四、回溯模式
1、回溯匹配
"12223".match(/12{1,3}3/) // 匹配5步就结束了
// 无回溯;匹配1,匹配2子模式,匹配3,顺利结束
"1223".match(/12{1,3}3/) // 1223
// 匹配到122以后,第4步在第四个位置,依然匹配字符串2,发现是3,于是回到上一步的状态,结束2{1,3}子模式
// 第5步回溯
// 第6步开始对3的匹配,在第四个位置匹配3,找到了,结束字符串3的匹配