由于最近做的项目涉及到比较多的转义字符,转义字符长时间不用已经遗忘了,每次需要的时候就需要找到ai生成,或者网络上搜索,所以复习一遍。
正则表达式(regular expression)
功能:字符串模式匹配,实现搜索和替换功能,描述规则的表达式。
字符
正则表达式的基本组成元素分为字符和元字符
字符:
就是基础的计算机字符编码,比如数字或者英文字母
javascript
const regex = /hello/;//要求全匹配
console.log(regex.test('hello,world')) //true
console.log(regex.test('hhhhhh')) //false
const regex = /[abc]/;//有一个匹配上就为true
console.log(regex.test('hello,happy')) //true
console.log(regex.test('car')) //true
元字符:
指的是标识特殊语义的字符,常见的元字符包括<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">.</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">^</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">$</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">*</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">+</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">?</font>
、<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">|</font>
等。
plain
. // 匹配除换行符以外的任意一个字符
^ // 匹配字符串的开始
$ // 匹配字符串的结束
\d // 匹配任意数字(相当于 [0-9])
\D // 匹配除了字符以外的
\w // 匹配字母、数字、下划线(相当于 [a-zA-Z0-9_])
\W // 匹配除了任意字母、数字、下划线
\s // 匹配任意空白字符
\S // 匹配非空白字符
一些栗子🌰:
javascript
const regex = /ab./
console.log(regex.test('ab\n')//false
console.log(regex.test('abc')//true
const regex = /^a/ //这里^要求所有字符都是以a开始 相同的$就是以什么结束
console.log(regex.test('apple')//true
console.log(regex.test('a')//true
单个字符
最简单的正则表达式就是由简单的数字和字母组成,没有特殊语义,实现一一对应的关系,比如我们要找到good里面的o,则/o/就可以了。
如果想要匹配特殊字符,就需要使用第一个元字符****,这是转义字符,让他后面的字符失去其本来的含义,变成最单纯的意思,比如:
特殊字符 | 正则表达式 | 记忆方式 |
---|---|---|
换行符 | \n | new line |
\f | form feed | |
回车符 | \r | return |
空白符 | \s | space |
制表符 | \t | tab |
垂直制表符 | \v | vertical tab |
回退符 | [\b] | backspace,用[]符号是避免和\b重复 |
多个字符
多个字符就需要使用集合和通配符的方式实现一对多的匹配
**集合:**用中括号显示[],比如/[123]/就可以同时匹配1,2,3三个字符;/[0-9]/用来匹配0-9的所有数字,元字符-用来表示区间范围;/[a-z]则可以匹配所有的英文小写字母
当匹配多个字符,即使有集合和区间的定义方式,还是很低效,所以在正则表达式中就衍生了一批用来同时匹配多个字符的简便正则表达式:
匹配区间 | 正则表达式 | 记忆方式 |
---|---|---|
除了换行符之外的任何字符 | . | |
单个数字,[0-9] | \d | digit |
除了[0-9] | \D | not digit |
包括下划线在内的单个字符,[A-Za-z0-9] | \w | |
非单字字符 | \W | |
匹配空白字符,包括空格、制表符和换行符 | \s | |
匹配非空白字符 | \S |
循环与重复
要实现多个字符的匹配我们只要多次循环,重复使用我们之前的正则就可以了
0|1
元字符?代表匹配一个字符或0个字符。
如果要匹配color和colour两个单词,就需要保证u这个字符是否出现都能被匹配到。所以正则表达式是:/colou?r/
>=0
元字符* 用来匹配0个字符或者无数个字符。通常用来过滤一些可有可无的字符串
>=1
元字符+ 适用于要匹配相同字符出现1次或者多次的情况
特定次数 量词
用{ }来指定
plain
{x}:x次
{min,max}:介于min次到max次
{min,} :至少min次
{0,max}:至多max次
分组与分组捕获
- 分组
- 使用圆括号
<font style="color:rgb(255, 80, 44);background-color:rgb(255, 245, 245);">()</font>
表示一个组,可以对组内的内容进行分组和捕获。例如:
- 使用圆括号
匹配年月日:
javascript
(\d{3})-(\d{2})-(\d{4}) // 捕获日期中的年、月、日
const regex = /(\d{4})-(\d{2})-(\d{2})/;// /d用来匹配数字
const date = "2024-12-26";
const match = date.match(regex);
console.log(match[1]); // "2024"
console.log(match[2]); // "12"
console.log(match[3]); // "26"
- 分组捕获:
- 比如/\d{4}-\d{2}-\d{2}/将整个日期作为一个组(group)匹配起来,我们吧这样的叫做Group0
- /(\d{4})-(\d{2})-(\d{2})/ 带上括号就会将其分组为多个,就可以通过$1、$2、$3进行获取
🌰:
javascript
co? //匹配o可以有一次或者0次 cool和cat都可以匹配到
do+ //o最少要有一次 可以有1次或者多次 door和dot都可以匹配到
po* //o可以有0次或者无数次 poor peet可以匹配到
go{2}d //good o必须有两个
go{2,3}d //good goood 2个到三个之间,具体参考3.4
(nd)+ //nd出现一次或者多次,具体参考4内容
(nd|dn)+ //anddnc ndnd dndn 都可以匹配
[123] //匹配方括号里的内容 1 2 3出现一个就可以 123 344都可以匹配上 和[a-z]一样
[^a-zA-Z]//匹配非字母的字符 注意这里要和元字符进行区分
高级匹配
懒惰匹配和贪婪匹配
html
<div>你好</div> <span>你好</span>
<.+> //用来匹配箭头括号中的HTML <div>你好</div><span>你好</span>
<!-- ? 开启懒惰匹配 正则会尽可能少的进行匹配 发现<div>已经符合匹配了,会直接匹配,然后向下匹配 -->
<.+?> //用来匹配箭头括号中的HTML标签 <div></div><span></span>
非捕获分组
(?:表达式)分组匹配之后,用?:过滤子表达式内容。也就是代码匹配,但是不保存。
🌰:
javascript
//使用捕获前
(\d{3})-(\d{2})-(\d{4}) // 捕获日期中的年、月、日
const regex = /(\d{4})-(\d{2})-(\d{2})/;// /d用来匹配数字
const date = "2024-12-26";
const match = regex.exec(date);
console.log(match[0]); // "2024-12-26"
console.log(match[1]); // "2024"
console.log(match[2]); // "12"
console.log(match[3]); // "26"
//使用非捕获后
(\d{3})-(\d{2})-(\d{4}) // 捕获日期中的年、月、日
const regex = /(\d{4})-(?:\d{2})-(\d{2})/;// /d用来匹配数字
const date = "2024-12-26";
const match = regex.exec(date);
console.log(match[0]); // "2024-12-26"
console.log(match[1]); // "2024"
console.log(match[2]);//匹配了12但是不输出
console.log(match[3]); // "26"
回漱
javascript
<[\w]+>.*<\/[\w]+>
//用来匹配一个HTML标签
//但是这种会匹配到<div>你好</span>
这个虽然可以匹配HTML开始和结束标签,但是却不能校验前后的一致性。如""并不是"
"的结束标签。
<[\w]+>.*</\1>>
javascript
<[\w]+>.*<\/\1>>
//"<\/\1>"其中"\1"就是引用第一个分组。这样一来我们就可以匹配正确的HTML标签了。
断言
也叫环视,只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果
- 正向先行断言:(?=表达式)所在位置的右侧必须匹配表达式
🌰:(?=.?[0-9])(?=.?[a-z])(?=.*?[A-Z]).{8,}
?= - 正向预查,要求字符串中必须包含至少一个数字
.*? 表示任意字符(除换行符外)出现0次或多次(非贪婪模式)
[0-9] 表示任意一个数字
- 反向先行断言:(?!表达式) 所在位置的右侧不能匹配表达式
方法
test() :该方法用于检测一个字符串是否匹配某个正则表达式,匹配 返回 true,不匹配返回 false。
javascript
console.log(/d+/.test('18 years old'))//true
exec():该方法用于检测字符串中对正则表达式的匹配。该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
配合string的方法
match 这个方法主要用来提取数据,它配合分组的()一起使用,可以很方便的提取数据。
replace这个api主要用于替换数据,多用于字符串的处理和转义。
split主要用于来切分字符串为数组,它的第一个参数也可以为正则的形式。
参考:https://juejin.cn/post/7132628898453880840?searchId=202501031339092E13563AEC4B5D8CB204#heading-44