正则表达式作用:
描述了一个规则,通过这个规则可以匹配一类字符串。
完成字符串的查找、验证和替换
1. 创建
// 1.字面量创建
const str = "abandon";
const reg1 = /a/;
console.log(reg1.test(str));
// 2.对象创建
const reg2 = new RegExp("a");
console.log(reg2.test(str));
// 区别
// 字面量创建无法识别变量
const v = 'a';
const reg3 = /v/
console.log(reg3.test(v)); //false
//对象创建可以识别变量
const reg4 = new RegExp(v);
console.log(reg4.test(v)); //true
// 但一般情况下,还是使用字面量创建更为常见
2. 元字符
- 所有大写和小写字母、所有数字、所有标点符号和一些其他符号等没有特殊定义的标点符号,都是“普通字符”。
- 元字符均查找的是单个字符,匹配多个时需要加量词
- 对于需要匹配元字符本身时,进行转义
- 巧用元字符匹配所有字符:[\s\S] 、[\d\D]
元字符 | 描述 |
---|---|
. | 查找除了换行和行结束符以外的所有字符。 |
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个引用 |
/ | 正则边界符 |
^n | 边界符,匹配任何开头为 n 的字符串或表示“非” |
n$ | 匹配任何结尾为 n 的字符串。 |
\w | 查找字母、数字、下划线 |
\W | 查找除了字母、数字、下划线的非单词字符。 |
\d | 查找数字。 |
\D | 查找非数字字符。 |
\s | 查找空白字符。 |
\S | 查找非空白字符。 |
\n | 查找换行符。 |
\r | 查找回车符。 |
量词 | 匹配数量 |
? | 表示量词或禁止贪婪 |
[] | 原子表 |
() | 原子组 |
断言匹配 | 相当于匹配条件 |
3. 量词
|- 量词仅作用于它前面紧跟的字符或组||
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。 |
n{X,Y} | 匹配包含 X 至 Y 个 n 的序列的字符串。 |
n{X,} | 匹配包含至少 X 个 n 的序列的字符串。 |
4. 模式修正符
模式修正符意在改变运行方式
模式 | 描述 |
---|---|
i | 不区分大小写 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止,只匹配一个叫做"不贪婪")。 |
m | 执行多行匹配。使边界字符 ^ 和 $ 匹配每一行的开头和结尾 |
模式可组合使用,不区分顺序,如: /gi
5. 原子表[ ]
- 将中括号[ ]称为原子表(字符簇),表示里面内容可选,去掉[ ]就表示完全匹配
- [ ]用连字号-可以表示一个字符的范围,这些也只表示一个字符,这是一个非常重要的。
- 正则表达式中的大多特殊符号,如果被包含于中括号中,则失去特殊意义, 只表示字符本意,但 \ [ ] : ^ - 除外。例如 " .+ "在[ ]外面表示除换行符以外的其他字符,在[ ] 里面就只表示 . +本身,不论如何转义;
- ^ 在原子表中表示取反 ,例如 [ ^\d ] 表示 " 除了数字 ",^在外面仍表示开头;- 在原子表中表示连接符 [0-9]
- 常见原子表的使用
表达式 | 描述 |
---|---|
[0-9] | 查找任何从 0 至 9 的数字 |
[a-z] | 查找任何从小写 a 到小写 z 的字符。 |
[A-Z] | 查找任何从大写 A 到大写 Z 的字符。 |
[adgk] | 查找给定集合内的任何字符。 |
[^adgk] | 查找给定集合外的任何字符。 |
6. 原子组( )
正则表达式中以一对括号()包裹的运算内容称为原子组, 但也有()不是原子组的情况,需要区分,例如断言匹配就不是原子组。
- 用处
const str = `
<h1>anxjas</h1>
<h2>xjsocniove</h2>
<h3>gjvhcfxd</h4>
`;
如上述内容,要想匹配出完整的h标签,正则需使用原子组:
str.match( /<h[1-6]>.</h[1-6]>/g )
但会匹配出h标签前后不一致的数据
为使前后保持一致,可使用原子组:
str.match( /(<h[1-6])>.</\1>/g )
- 原子组的引用
- 正则表达式中使用 \ 后面加数字n表示与第n个原子组一致 \1 \2 \3 ,依次从左往右数括号数量即可
- 在replace替换方法中直接使用 $ 符完成引用,$ 后面加数字n,表示第n个原子组,$n表示匹配到的第n个原子组的内容
const reg1 = /<(h[1-6])>(.*)<\/\1>/ig;
console.log(str.replace(reg1,'$2'));
- 在replace回调函数中,第一个参数是匹配到的整体
剩余参数是原子组的组合,args[0]:匹配到的第一个原子组的内容
str.replace(reg,(v,...args)=>{
console.log(v)
console.log(args);;
// v 即是正则匹配到的整体
// args是原子组的组合
})
3.原子组别名
当觉得$1 $2 不够清晰明了时,可以为原子组起别名
起名: (?<自定义名称>)
使用: $<自定义的名称>
const reg2 = /<(h[1-6])>(?<two>.*)<\/\1>/ig;
console.log(str.replace(reg2,'$<two>'));
7. 贪婪和禁止贪婪 “ ?”
上面的量词中看到,” ? “表示0个或一个,表示可选;
除此之外,“ ?”还有禁止贪婪的作用;
如何区分?
- 当“ ?”前面是量词,例如 + * {} ,表示禁止贪婪
// 量词加?表示禁止贪婪,往最少的一个方向去
const str = 'hddddd';
console.log(str.match(/hd+/))
console.log(str.match(/hd+?/));
console.log(str.match(/hd*?/));
console.log(str.match(/hd{2,}?/));
- 当” ?“前面是除量词以外的普通字符、原子表或原子组,表示前面内容可选
8. 断言匹配
- 断言就是指明某个字符串前边或者后边,将会出现满足某种规律的字符串。
- 断言匹配的()不是原子组,不出现在匹配结果中
断言 | 描述 |
---|---|
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
?<=n | 匹配任何其前面紧接指定字符串 n 的字符串。 |
?<!n | 匹配任何其前面没有紧接指定字符串 n 的字符串。 |
举例:电话号码模糊匹配
const tel = '13578450356';
const reg = /(?<=\d{7})\d{4}/;
console.log(tel.replace(reg,(v)=>{
return "*".repeat(4);
}));
正则对象属性lastIndex
量词 | 描述 |
---|---|
lastIndex | 一个整数,标示开始下一次匹配的字符位置。 |
// 因为exec实际上是一个迭代器,正则有一个lastindex的属性,
// 正则匹配检索到一个之后会暂停,从检索的位置再搜索,lastindex会变化,最后找不到的时候,lastindex为0
// 统计字符出现次数
const str = "hello,world";
const reg = /l/g;
let count = 0;
console.log(reg.lastIndex);
while(res = reg.exec(str)){
count++;
console.log(reg.lastIndex);
}
console.log(reg.lastIndex);
console.log(count);
正则对象的方法
方法 | 描述 |
---|---|
exec | 匹配字符串,返回找到的值,并确定其位置。迭代器,lastindex |
test | 在所搜索的字符串中是否存在正则表达式模式对应的匹配。返回 true 或 false。 正则验证 |
支持正则表达式的字符串方法
方法 | 描述 |
---|---|
match | 找到一个或多个正则表达式的匹配。 |
replace | 替换与正则表达式匹配的子串。 |
split | 根据正则匹配到的内容分割字符串数组。 |
search | 搜索字符串中是否存在满足正则的字串,返回索引值 |