B 站视频

第一节 掌握最基本的匹配

正则表达式真好玩,本篇带你掌握最基本的一些匹配。

JS 中的 RegExp 对象

在 JavaScript 中,RegExp 对象是一个预定义了属性和方法的正则表达式对象。

详细可以参考 菜鸟教程-正则表达式

在本次以及之后的内容,会通过使用 match() 、exec()、replace()等方法来执行我们编写的正则表达式。

匹配纯文本

直接上例子吧,如下我们是使用字符串的匹配,使用了 match() 方法,而我们写法并不是通过 new RegExp 的做法,而是比较常用的双斜线的方式,如下:

let str = 'The best things in life are free!';
let regExp = /free/;
let res = str.match(regExp);
console.log(res); // Array ["free"]

解释一下如上代码,想必大家对于上文所说的 match() 方法就比较清楚了。

代码的第 1 行就是创建一个纯字符串的文本,代码第 2 行创建了一个 RegExp,编写我们本次的正则表达式,代码第 3 行就是执行我们编写的正则表达式,代码第 4 行打印结果,而 match() 方法检索返回一个字符串匹配正则表达式的结果。

现在,你已经掌握了基本的正则匹配了,是不是比较简单呢?别急,我们继续往后看。

匹配多个结果

根据上一节,你已经掌握了基本的匹配,我们看如下例子:

let str = 'I want to be free, the best thing in life is freedom';
let regExp = /free/;
let res = str.match(regExp);
console.log(res); // Array ["free"]

发现问题没有,这个执行结果只返回了第一个 free 匹配,如果我想要返回所有的匹配结果呢?

直接先给出例子来:

let str = 'I want to be free, the best thing in life is freedom';
let regExp = /free/g;
let res = str.match(regExp);
console.log(res); // Array ["free", "free"]

对比代码即可知道,多了一个 g,联想到英文单词 global,这个 g 是一个修饰符,表示全局匹配,找到所有满足条件的组合,那么问题解决。

字母大小写问题

上文中我们对 free 进行了全局匹配,那再看看如下例子:

let str = 'Free to fly, freedom is our pursuit';
let regExp = /free/g;
let res = str.match(regExp);
console.log(res); // Array ["free"]

发现,我们只返回了对应 free 的匹配,首字母大写的 Free 并没有被匹配到,但有时候我们需要不关注字母的大小写,该怎样呢?

如下例子:

let str = 'Free to fly, freedom is our pursuit';
let regExp = /free/gi;
let res = str.match(regExp);
console.log(res); // Array ["Free","free"]

对比代码就很清楚啦,在原本的全局匹配修饰符上多了一个 i,这个是 ignoreCase 的简称,代表忽略字母的大小写,那么问题解决。

匹配不确定的文本

在上文中,比如我们匹配 free 这个字符串,这里是很清楚知道要匹配这四个字母,但是有时候我们可能需要的是首尾确定但中间部分字符不确定的情况,比如在这段文本中,我们想要匹配 以 f 开头然后 t 结尾的字符串,并且字符串长度是 5 位,需要全局匹配并且忽略大小写。

那么就有三位是不确定的,该怎样匹配呢?

There are really many front-end big guys, learn from you front-end big guys

直接看如下例子:

let str = 'There are really many front-end big guys, learn from you front-end big guys';
let regExp = /f...t/gi;
let res = str.match(regExp);
console.log(res); // Array ["front","front"]

发现我们可以通过 . 用来匹配任意字符,也可以说是匹配我们不确定的字符,问题解决。

匹配特殊的字符

上一小节,我们通过 . 匹配到了不确定的字符,但是会有一个问题,假如我们的文本中本来就有 . 呢?

直接看如下例子吧:

let str = 'The react.js is used by many people';
let regExp = /react\.js/gi;
let res = str.match(regExp);
console.log(res); // Array ["react.js"]

在本例中 . 不再是为了匹配不确定的字符了,而是我们明确需要匹配的字符。通过 \ 可以实现效果,这个 \ 表示转义,转义之后的 . 就失去了原本匹配不确定字符(也可以说是匹配任意字符)的功能了,这个问题就解决了。

结尾

本篇文章就到此结束啦,感谢您的阅读。喜欢我的文章可以点点关注,下次我们还能遇见,关注就是最大的动力啦。

我是「一百个Chocolate」,一位狮子座的程序员,坚持写博客的第 4 年,座右铭:学如逆水行舟,不进则退。

第二节 掌握进阶的匹配操作

正则表达式真好玩,上一篇大家应该掌握了一些基础的操作,想必应该掌握的还不错,那么本篇带你掌握一些进阶操作。

介绍元字符

正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。

元字符使正则表达式具有处理能力。

所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

以上关于元字符的介绍内容来自网络,仅供参考。

而本次要介绍的元字符是 [](和),有什么作用呢?

上一篇我们了解到可以通过英文句号 . 来匹配任意字符,但有时候我们就很明确从某些字符里面匹配就好了。比如我们就只想匹配 C 和 H 两个字符。

在正则表达式里面,我们可以通过元字符 [] 来定义一个字符集合。这样就能够匹配集合里面的成员了。

直接看例子吧:

let str = 'Chocolate wants 100,000 fans, Chocolate love chocolate';
let reg = /[Cc]hocolate/g;
let res = str.match(reg);
console.log(res); // ['Chocolate', 'Chocolate', 'chocolate']

从结果我们可以发现,匹配到了 chocolate,首字母大小写均可。

接下来开始我们的例子可能会变成数组了,如下:

let arr = ['Choco','choco', 'nhoco', 'yhoco', 'hearling'];
let reg = /[Ccyn]hoco/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['Choco', 'choco', 'nhoco', 'yhoco']

以上例子也是比较清楚了,想必对于元字符和的概念应该掌握不错了。

掌握这个知识之后,你就可以匹配已知的多个字符中的某一个了,并且也可以缩小全局匹配字母大小写问题的范围。

匹配数字

在之前的内容,我们好像一直都是匹配字符串中的字母,没有匹配过数字问题,那么现在就来利用元字符来解决匹配数字的一系列问题。

直接来看例子吧:

let arr = ['choco1','choco2', 'nhoco3', 'yhoco6', 'hearling'];
let reg = /[Ccyn]hoco[0123456789]/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['choco1', 'choco2', 'nhoco3', 'yhoco6']

我们通过 [] 定义了数字类的集合,比较好理解,就不多解释了。

但这样写法会不会觉得有点麻烦呢?可以省略点写嘛。

当然可以,直接给出如下例子:

let arr = ['choco1','choco2', 'nhoco3', 'yhoco6', 'hearling'];
let reg = /[Ccyn]hoco[0-9]/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['choco1', 'choco2', 'nhoco3', 'yhoco6']

集合区间

我们可以在集合中通过 0-9 来进行数字集合的省略,这个做法就叫做利用字符集合区间。

当然,有数字集合也会有字母集合,如下:

A-Z,a-z 等等其它集合区间,但是得注意如果你想包括字母大小写的话,像 A-z 这样是不行的,可以查看 ASCII 字符表,Z 到 a 这个不是连续的,还会有其它字符,所以一般这样是不行的。

有这些组合了,想必大家也能写出很多一些进阶的匹配了,在这里我就不举例子了,大家掌握这个知识即可。

区间之外

送你离开,千里之外…

上一小节我们掌握了区间的使用,但这是我们知道的区间,对于区间之外的呢?

或者说有时候我们知道我们自己除开字母了其它的都想匹配,或者除开数字了其它都想匹配,这又该如何做呢?

如果你是暴力大法的忠实粉丝,你可能会枚举全部的情况,但有时候能考虑完全嘛?显然不可以。

其实很简单,取个反不就好了吗?直接看如下例子:

let arr = ['choco1','chocol', 'nhoco3', 'yhoco6', 'hearling'];
let reg = /[Ccyn]hoco[^0-9]/g;
let res = arr.filter(item=>item.match(reg));
console.log(res); // ['chocol']

看例子,取反字符为 ^。本例子是将最后一个字符匹配非数字的,通过取反操作方便了许多,不用暴力考虑很多种情况了。

小结

芜湖,本小节内容到底就结束啦,感谢各位的阅读,我们期待下一篇吧。

第三节 元字符真好玩

正则表达式真好玩, 上一篇中我们提及了元字符的概念,本篇带你了解更多元字符的内容,真好玩。

空白字符怎么匹配

在之前的内容我们要么是匹配字母,要么是匹配数字,亦或是匹配一些特殊的字符(通过转义),那一些空白字符我们该如何匹配呢?

比如换行,回车,Tab 键,删除等等,在实际需求中,我们可能需要去掉这些空白字符或者进行替换操作。

看本篇的标题可能就知道了,我们又会用到元字符,那么现在介绍一下关于空白元字符

元字符 作用
\n 换行符
\r 回车符
\s 匹配任何空白字符,包括空格、制表符、换页符等等
\t 制表符(Tab 键)
\v 垂直制表符
\f 换页符
[\b] 回退(并删除)一个字符(Backspace键)

关于这个空白元字符比较常见的可能就是前三个了,大家能记下来是最好的,不能记的话还能回翻我的博客。

那么,现在来简单使用一下上述空白元字符吧,例子如下:

let str = 'There are really many front-end big guys';
let reg = /\s/g;
let res = str.match(reg);
console.log(res); // [' ', ' ', ' ', ' ', ' ', ' ']

这个例子比较简单,就是使用一下 \s 来匹配一下空白的字符,注意上述表格所说,会包括空格、制表符、换页符等等,等价于 [ \f\n\r\t\v]

同时还要注意 Unicode 正则表达式会匹配全角空格符。

而这个 Unicode 正则表达式是啥呢,可以给大家简单举例:

num.match('\u0661\u0662\u0663')

观察表格,回顾一下我们之前讲过的元字符,发现规律了吗,大部分的元字符都需要转义字符 \,比如我们上述所使用的 \s,如果没有转义操作,那么将只会匹配字符本身。

特殊字符怎么匹配

从上文到现在,我们已经学会了一些特定的匹配,对于任意字符呀,然后多个匹配,还使用了字符集合、空白字符等,但元字符的知识还不仅仅局限于此。

我们继续来看看吧,对于一些特殊字符,其实也并不特殊,可以说是更加简化的写法。

数字与非数字简化

在之前我们掌握可以通过 [0-9] 来简化 [0123456789] 的写法,那么现在再来教你一招,使用数字元字符。

元字符 作用
\d 等价于 [0-9]
\D 等价于 [^0-9]

直接看例子吧,继续使用我们之前的例子:

\d 使用:

let arr = ['choco1','choco2', 'nhoco3', 'yhoco6', 'hearling'];
let reg = /[Ccyn]hoco\d/g;
let res = arr.filter(item=>item.match(reg));
console.log(res) // ['choco1', 'choco2', 'nhoco3', 'yhoco6']

\D 使用

let arr = ['choco1','choco2', 'nhoco3', 'yhoco6', 'hearling', 'chocol'];
let reg = /[Ccyn]hoco\D/g;
let res = arr.filter(item=>item.match(reg));
console.log(res) // ['chocol']

字母数字与非字母数字的简化

看标题可能比较拗口,直接看下述表格举例吧:

元字符 作用
\w 等价于 [a-zA-Z0-9_]
\W 等价于 [^a-zA-Z0-9_]

\w 会匹配字母和数字,并且还会包括下划线,这个值得注意,下划线可以匹配得到。

\W 就是与上述相反。

\w 使用:

let arr = ['choco1','choco2', 'nhoco3', 'yhoco6', 'hearling', 'chocol'];
let reg = /\whoco\D/g;
let res = arr.filter(item=>item.match(reg));
console.log(res) // ['chocol']

\W 使用:

let arr = ['C++','JAVA','PHP','JS'];
let reg = /[Cc]\W\W/g;
let res = arr.filter(item=>item.match(reg));
console.log(res) // ['C++']

空白字符与非空白字符

这个其实在上文中就有给大家提及过,在这里就只通过表格给大家展示了:

元字符 作用
\s 等价于 [\f\n\r\t\v],代表空白字符
\S 等价于 [^\f\n\r\t\v],代表非空白字符

进制的匹配问题

想必大家也会遇到一些算法题,可能会需要匹配进制,然后将某个进制转化等等,比较常见的就是十六进制、八进制等。

那么在这里来举例来说明一下:

十六进制的表示通过前缀 \x 来表示,我们可以试着玩玩:

console.log('Choco\xA0late') // Choco late
console.log('Choco\xAClate') // Choco¬late
console.log('Choco\xFClate') // Chocoülate
console.log('Choco\xBClate') // Choco¼late
console.log('Choco\xABlate') // Choco«late

而八进制的表示通过前缀 \0 来表示,我们也可以试着玩玩:

console.log('Choco\011late') // Choco	late
console.log('Choco\00late') // Chocolate
console.log('Choco\061late') // Choco1late
console.log('Choco\071ate') // Choco9ate
console.log('Choco\066late') // Choco6late

小结

不知不觉已经坚持输出第三篇博客了,希望继续努力更新完整个系列~

本小节内容到底就结束啦,感谢各位的阅读,我们期待下一篇吧。