JavaScript 正则表达式学习

本文作者: ych6666
原文链接: https://blog.csdn.net/ych6666/article/details/122958097

正则表达式作用:
描述了一个规则,通过这个规则可以匹配一类字符串。
完成字符串的查找、验证和替换

创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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
// 但一般情况下,还是使用字面量创建更为常见

元字符

  • 所有大写和小写字母、所有数字、所有标点符号和一些其他符号等没有特殊定义的标点符号,都是“普通字符”。
  • 元字符均查找的是单个字符,匹配多个时需要加量词
  • 对于需要匹配元字符本身时,进行转义
  • 巧用元字符匹配所有字符:[\s\S] 、[\d\D]
元字符描述
.查找除了换行和行结束符以外的所有字符。
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个引用
/正则边界符
^n边界符,匹配任何开头为 n 的字符串或表示“非”
n$匹配任何结尾为 n 的字符串。
\w查找字母、数字、下划线
\W查找除了字母、数字、下划线的非单词字符。
\d查找数字。
\D查找非数字字符。
\s查找空白字符。
\S查找非空白字符。
\n查找换行符。
\r查找回车符。
量词匹配数量
?表示量词或禁止贪婪
[]原子表
()原子组
断言匹配相当于匹配条件

量词

|- 量词仅作用于它前面紧跟的字符或组||

量词描述
n+匹配任何包含至少一个 n 的字符串。
n*匹配任何包含零个或多个 n 的字符串。
n?匹配任何包含零个或一个 n 的字符串。
n{X}匹配包含 X 个 n 的序列的字符串。
n{X,Y}匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,}匹配包含至少 X 个 n 的序列的字符串。

模式修正符

模式修正符意在改变运行方式

模式描述
i不区分大小写
g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止,只匹配一个叫做”不贪婪”)。
m执行多行匹配。使边界字符 ^$ 匹配每一行的开头和结尾

模式可组合使用,不区分顺序,如: /gi

原子表[ ]

  • 将中括号[ ]称为原子表(字符簇),表示里面内容可选,去掉[ ]就表示完全匹配
  • [ ]用连字号-可以表示一个字符的范围,这些也只表示一个字符,这是一个非常重要的。
  • 正则表达式中的大多特殊符号,如果被包含于中括号中,则失去特殊意义, 只表示字符本意,但 \ [ ] : ^ - 除外。例如 “ .+ “在[ ]外面表示除换行符以外的其他字符,在[ ] 里面就只表示 . +本身,不论如何转义;
  • ^ 在原子表中表示取反 ,例如 [ ^\d ] 表示 “ 除了数字 “,^在外面仍表示开头;- 在原子表中表示连接符 [0-9]
  • 常见原子表的使用
表达式描述
[0-9]查找任何从 0 至 9 的数字
[a-z]查找任何从小写 a 到小写 z 的字符。
[A-Z]查找任何从大写 A 到大写 Z 的字符。
[adgk]查找给定集合内的任何字符。
[^adgk]查找给定集合外的任何字符。

原子组( )

正则表达式中以一对括号()包裹的运算内容称为原子组, 但也有()不是原子组的情况,需要区分

  1. 用处

    1
    2
    3
    4
    5
    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 )

  2. 原子组的引用

  • 正则表达式中使用 \ 后面加数字n表示与第n个原子组一致 \1 \2 \3 ,依次从左往右数括号数量即可
  • 在replace替换方法中直接使用 $ 符完成引用,$ 后面加数字n,表示第n个原子组,$n表示匹配到的第n个原子组的内容
    1
    2
    const reg1 = /<(h[1-6])>(.*)<\/\1>/ig;
    console.log(str.replace(reg1,'$2'));
  • 在replace回调函数中,第一个参数是匹配到的整体
    剩余参数是原子组的组合,args[0]:匹配到的第一个原子组的内容
1
2
3
4
5
6
str.replace(reg,(v,...args)=>{
console.log(v)
console.log(args);;
// v 即是正则匹配到的整体
// args是原子组的组合
})

3.原子组别名
当觉得$1 $2 不够清晰明了时,可以为原子组起别名
起名: (?<自定义名称>)
使用: $<自定义的名称>

1
2
const reg2 = /<(h[1-6])>(?<two>.*)<\/\1>/ig;
console.log(str.replace(reg2,'$<two>'));

贪婪和禁止贪婪 “ ?”

上面的量词中看到,” ? “表示0个或一个,表示可选;
除此之外,“ ?”还有禁止贪婪的作用;
如何区分?

  • 当“ ?”前面是量词,例如 + * {} ,表示禁止贪婪
1
2
3
4
5
6
7
// 量词加?表示禁止贪婪,往最少的一个方向去
const str = 'hddddd';
console.log(str.match(/hd+/))
console.log(str.match(/hd+?/));
console.log(str.match(/hd*?/));
console.log(str.match(/hd{2,}?/));

  • 当” ?“前面是除量词以外的普通字符、原子表或原子组,表示前面内容可选

断言匹配

  • 断言就是指明某个字符串前边或者后边,将会出现满足某种规律的字符串。
  • 断言匹配的()不是原子组,不出现在匹配结果中
断言描述
?=n匹配任何其后紧接指定字符串 n 的字符串。
?!n匹配任何其后没有紧接指定字符串 n 的字符串。
?<=n匹配任何其前面紧接指定字符串 n 的字符串。
?<!n匹配任何其前面没有紧接指定字符串 n 的字符串。

举例:电话号码模糊匹配

1
2
3
4
5
6
7
8

const tel = '13578450356';

const reg = /(?<=\d{7})\d{4}/;

console.log(tel.replace(reg,(v)=>{
return "*".repeat(4);
}));

正则对象属性lastIndex

量词描述
lastIndex一个整数,标示开始下一次匹配的字符位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 因为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搜索字符串中是否存在满足正则的字串,返回索引值

评论