thby

导航

 

正则表达式(Regular Expressions),简称 regex(音译 瑞爱宅克斯)或者 regexp,用来查找字符串(Strings)并进行并进行一系列操作。

regex的表现形式不同于之前接触过(如果以后有机会再补 Javascript 的随笔吧)的数据类型:

1 // 字符串
2 let str = "only you";
3 
4 // 正则表达式
5 let regex = /only/;

也就是说regex会包含两个 / ,接下来看看具体用法,从最简单粗暴的开始。

既然是查找,那这个找的过程就需要涉及到一个方法(Method):test()

1 // 字符串
2 let str = "only you";
3 
4 // 正则表达式
5 let regex = /only/;
6 
7 // 查找 only 是否包含于 "only you" 中
8 let result = regex.test(str);

test的语法(或者说使用方式)如上所示:正则表达式.test(字符串),字符串包含正则表达式返回true,反之为false。用这种方法我们可以查找特定的字符串是否包含于其他字符串中。

接下来,在查找的过程当中,还会涉及到大小写的问题,在没有特殊说明的情况下,大小写是严格区分的。这个时候需要引入标志(flag)。标志位于最后一个 / 的后面。

1 // 字符串
2 let str = "Only you";
3 
4 // 正则表达式
5 let regex = /only/i;
6 
7 // 查找 only 是否包含于 "Only you" 中
8 let result = regex.test(str);

上面这个例子只做了一些小小的改动,可以看到字符串中的字母出现了大写而正则表达式的查找内容没有变化,而是在最后加了一个 i ,这个标志就是用来不区分大小写的,可以理解为忽略(ignorance)或者无所谓(insensitive)的缩写。

考虑到我们介绍的 test() 方法只能返回布尔值(Boolean),但正则表达式既然是查找特定字符串,肯定还会有获取值的方法。因此为了进一步介绍,我们需要引入新的方法:match()

match()和test()的区别不仅限于返回值,在语法方面也需要我们区分。

1 // 字符串
2 let str = "only you";
3 
4 // 正则表达式
5 let regex = /only/;
6 
7 // 查找字符串中有没有 only ,有的话将其作为返回值
8 let result = str.match(regex);

match()的语法:字符串.match(正则表达式),而且如果在编译器中操作一下会发现,其实调用match后的返回值是一个数组(Array)。数组是一系列数据类型的集合,接下来要谈的内容就会涉及到数组。

在使用正则表达式对字符串进行查找的时候,我们还会发现一些其他的问题,比如查找的次数。

1 // 字符串
2 let str = "only only only only you";
3  
4 // 正则表达式
5 let regex = /only/;
6  
7 // 查找字符串中有没有 only ,有的话将其作为返回值
8 let result = str.match(regex);

在字符串中加上了三个 only 之后,我们如果log(指 Javascript 里的 console.log() 方法)一下,会得到如下结果:

 

前面的 Array 表示数组, 后面的 () 表示数组中元素的个数, (1) 就表示该数组只有一个元素。这个结果与字符串中只有一个 only 没有任何区别,所以我们需要引入一些其他的东西。

标志 g 为我们解决了这个问题,与其他标志一样需要写在最后一个 / 之后,用来查找字符串中所有符合特定字符串的值并返回。

1 // 字符串
2 let str = "only only only only you";
3  
4 // 正则表达式
5 let regex = /only/g;
6  
7 // 查找字符串中有没有 only ,有的话将其作为返回值
8 let result = str.match(regex);
9 console.log(result);

按照如上方式log的结果为

 

即所有字符串中的四个 only 都被成功匹配了。

正则表达式的意义不仅在于查找特定的、具体的内容,主要还服务于那些不确定的字符查找。随着需求的提升,我们就需要引入新的东西。

在举下一个例子之前,先介绍几个单词,然后用这几个单词造个句子:attitude(态度)、altitude(高度)、aptitude(天赋)。

"Our aptitude may decided start of our life, but life's altitude depends on our attitude towards it." —— thby

我觉得这几个长得差不多的单词都非常好,然后想用正则表达式把他们找出来,怎么办?

还是先选择最简单粗暴的方法,当面临多个匹配的时候,正则表达式为我们提供了”或“(or)这个选项:| (注意:这不是 /

1 // 字符串
2 let str = "Our aptitude may decide start of our life, but life's altitude depends on our attitude towards it.";
3  
4 // 正则表达式
5 let regex = /attitude|altitude|aptitude/g;
6  
7 // 查找字符串中有没有 attitude 或者 altitude 或者 aptitude ,有的话将其作为返回值
8 let result = str.match(regex);
9 console.log(result);

我们可以通过这个达到我们想要的结果,但这其实不是我挑选这几个词的真正原因,因为它们的唯一的区别都在于单词的第二个字母,举这个例子是为了引出通配符(Wildcard). (不仅放大了字体而且还加粗了,没有看错就是个 . 而已)

1 // 字符串
2 let str = "Our aptitude may decided start of our life, but life's altitude depends on our attitude towards it.";
3  
4 // 正则表达式
5 let regex = /a.titude/g;
6  
7 // 查找字符串中有没有 attitude 或者 altitude 或者 aptitude ,有的话将其作为返回值
8 let result = str.match(regex);
9 console.log(result);

按照这种方法我们会得到与上面一个例子相同的结果。这时我们发现把那个唯一有区别的位置换成 . 之后,表达式变得简洁了许多,而当需要查找类似的情况很复杂的时候,通配符的作用才会更明显。

话又说回来,通配符的可以用来匹配任何一个字符,那如果想要把查找的字符限定在一个范围内又要引入什么?

对上面那个例子进行调整来进行说明:

1 // 字符串
2 let str = "Our aptitude may decide start of our life, but life's altitude depends on our attitude towards it.";
3  
4 // 正则表达式
5 let regex = /a[lpt]titude/g;
6  
7 // 查找字符串中有没有 only ,有的话将其作为返回值
8 let result = str.match(regex);
9 console.log(result);

[lpt]直接限定了该位置的字母只能是字母L或者字母P或者字母T,可以达到限制范围的目的,但是需要自行键入具体范围,当问题复杂化后需要其他解决办法。

1 // 字符串
2 let str = "Our aptitude may decide start of our life, but life's altitude depends on our attitude towards it.";
3  
4 // 正则表达式
5 let regex = /a[l-p]titude/g;
6  
7 // 查找字符串中有没有 altitude 或者 aptitude ,有的话将其作为返回值
8 let result = str.match(regex);
9 console.log(result);

把之前[lpt]的位置换成了 [l-p] ,这两种都是字符集(Character classes)的表示方法,例子中表示字母L到字母P之间(包含两端)的任意字母,因此结果只包含两个,而不包含attitude(字母T不在范围内)。这种方法对于数字也同样适用,在这里就不多举例子了。

posted on 2021-01-26 14:33  thby  阅读(88)  评论(0编辑  收藏  举报