写点什么

正则表达式学习笔记(二)

作者:lxmoe
  • 2022-11-18
    辽宁
  • 本文字数:1789 字

    阅读完需:约 6 分钟

五种断言

断言指的是对模式的边界匹配,比如在头部开始,或者在尾部开始,又或者指定一个边界开始,基本分为五种断言方式,分别为边界断言先行断言先行否定断言后行断言后行否定断言

边界断言

边界断言可以在指定边界进行匹配,常用的元字符^$^可以在头部进行匹配,$可以在尾部进行匹配


let reg = /^a/;let _reg = /a$/;let str = "ba";console.log(reg.test(str)); // falseconsole.log(_reg.test(str)); // true
复制代码


"ba"头部为b,所以并没有被/^a/匹配到,而"ba"的尾部为a所以可以被/a$/匹配到。

先行断言

先行断言:/x(?=y)/,在y前面的区域对x进行匹配


let reg = /a(?=b)/;let str = "ba";let _str = "ab";console.log(reg.test(str)); // falseconsole.log(reg.test(_str)); // true
复制代码


上面的例子使用先行断言/a(?=b)/,只有在ab可以被匹配到

先行否定断言

先行否定断言:/x(?!y)/只有不在y前面的区域才能对x进行匹配,可以用数学集合来解释,先行断言与先行否定断言的并集为全集


let reg = /a(?!b)/;let str = "ca";let _str = "ab";console.log(reg.test(str)); // trueconsole.log(reg.test(_str)); // false
复制代码


上面的例子使用先行否定断言/a(?!b)/,即只有不在b的区域内可以对a匹配,而ca没有这个区域。

后行断言

后行断言:/(?<=y)x/,与先行断言方向相反,即在y后的区域对x进行匹配


let reg = /(?<=b)a/;let str = "ba";let _str = "ab";console.log(reg.test(str)); // trueconsole.log(reg.test(_str)); // true
复制代码


上面例子使用后行断言/(?<=b)a/,只有在b后的区域内可以对a匹配

后行否定断言

后行否定断言:/(?<!y)x/,只有不在y后面的区域才能对x进行匹配,与后行断言的并集为全集


let reg = /(?<!b)a/;let str = "abc";let _str = "ba";console.log(reg.test(str)); // trueconsole.log(reg.test(_str)); // false
复制代码

三种方式

正则表达式有三种创建方式,分别为字面量创建构造函数+字面量创建构造函数+字符串创建

字面量创建

let reg = /a/;
复制代码

构造函数+字面量创建

通过RegExp构造函数创建正则,本质上正则表达式是一个对象实例,参数是字面量形式。


let reg = new RegExp(/a/);
复制代码

构造函数+字符串创建

通过RegExp构造函数创建正则,参数是字符串形式。


let reg = new RegExp("a");
复制代码

不同之处

会有人想这三种方法就直接使用字面量创建不是最简单的形式么,其实字面量创建和构造函数创建在编译时机有着很大的区别


  • 字面量创建的正则会在脚本运行后进行编译

  • 构造函数创建的正则会在脚本运行时进行编译


编译时机上的区别让两种形式的使用场景发生了变化


  • 脚本运行后编译适用于正则保持不变的情况,这样会使性能更加稳定

  • 脚本运行时编译适用于正则需要随着用户的交互发生变化,这样就需要构造函数来创建和脚本实时编译。

多种匹配

简单匹配

简单匹配即想要匹配特定的字符,比如我想要在一串字符串内寻找某个特定的词,可以使用简单模式进行直接匹配,这也是其特点,简单模式直接且严格。


let reg = /abc/;let str = "abcdf";let _str = "a bcdf";console.log(reg.test(_str)); // falseconsole.log(reg.test(str)); // true
复制代码

组匹配

组匹配可以搭配()-元字符使用,可以匹配多组数据,常用来切割时间戳等场景


let reg = /(\d{4})-(\d{2})-(\d{2})/;let str = "2022-07-08";console.log(reg.exec(str));
复制代码


还可以使用具名组匹配可以为匹配结果指定一个名字


let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;let str = "2022-07-08";console.log(reg.exec(str));
复制代码


具名组匹配的结果会被添加到groups属性中,那么我们还可以通过解构赋值来拿到结果


const { groups: { year } } = reg.exec(str);console.log(year); // 2022
复制代码

范围匹配

使用[]=元字符进行范围匹配


let reg = /[0-9]/let str = "404"console.log(reg.test(str)) // true
复制代码


如上匹配0-9区间内的数字,还可以通过范围匹配来匹配所有的汉字,字母等等

多次匹配

使用+{x,y}*元字符来特定匹配某规则 n 次


使用+可以匹配多次


let reg = /[0-9]/;let _reg = /[0-9]+/;let str = "500a502";console.log(str.match(reg)); // 5console.log(str.match(_reg)); // 500
复制代码


使用{x,y}可以指定次数范围


let reg = /[0-9]{1,2}/;let str = "500a5";console.log(str.match(reg)); // 50
复制代码


其中xy表示一个范围,可以为{x}{x,}{x,y}分别代表x次,x到无穷次与xy次,而*等价于`{0,}

发布于: 刚刚阅读数: 5
用户头像

lxmoe

关注

还未添加个人签名 2022-08-06 加入

还未添加个人简介

评论

发布
暂无评论
正则表达式学习笔记(二)_正则表达式_lxmoe_InfoQ写作社区