阅读 816

看完不会正则,up把正则吃了

前言

现在很多地方用到正则,比如常见的邮箱,手机等

从前遇到这些,都是顺手google或者一个个的试,毫无章法

每次想要看正则,结果被一堆文章给看怕了。

最短的也是"30分钟教会正则",

但是30分钟看完还是输入了太多的东西,没有概括和快速实例入门

写这篇也是为了希望将来我忘记正则时,有篇笔记可以让我快速想起来

毕竟,正则这东西,谁(wo)也记不了一辈子!

如果你觉得我帮助到你的话,敬请点赞!


Point

私以为正则最关键的一个语法就是分类,学好分类,天下无不能匹配之字符串。

所谓分类,就是一(n)双圆括号()! 官方名词:子表达式


精准匹配

来,我们举个简单的栗子。

找出一句话中的Christmas,举例为我霉的一句歌词:

We can leave the Christmas lights up , util January.

我们分类的依据便是,Christmas

来写下第一行正则表达式:/(Christmas)/

(如果只有一个匹配值,我们通常会去掉圆括号,即/Christmas/)


匹配结果是:

Christmas


区间匹配

那升级一下,来一道小的应用题:

把一句话中的所有单词分割成单个字符串

我们把所有由a-zA-Z的组成的单词来做分类依据

即/a-zA-Z/,但是聪明的朋友肯定知道这样是不行的

因为这样会是精准匹配,匹配的是一句话中"a-zA-z"这个限定字符串

在这里我们需要了解区间这个概念,

通俗点说就是你要匹配的字符串将在这个区间内,区间用 [ ] 表示

/([a-zA-Z])/表示匹配所有a-zA-Z的单个字符


匹配结果:

W

n

e

a ...


多次匹配

如果我想获取所有单词呢,这也是一道常见的初级题目

分类依据依然是由a-zA-Z的组成的单词

只是要允许接着匹配单个字符后的其他字符,即匹配前面的子表达式一次或多次,多次匹配用 + 号来表示。

这么说有点绕,还是直接上图吧

我们的表达式为/([a-zA-Z])+/,代表()里的子表达式可以执行多次


看到这张图,就顿时清晰了,我们所说的分组即是Group,+即是1 or more time

匹配结果:

We 

can 

leave

the 

Christmas 

lights 

up 

util 

January


非字符匹配

这时候考官又出题了,我还想匹配到这个,或者.符号啊,或者其他!号什么的。

我们的依据是匹配单词即([a-zA-Z])+,或,符号和.符号 ([\,\.])

(特殊字符,通过在字符前添加 \ 来转换)

正则提供了 | 符号来表示或关系,把所有分组通过 | 连接起来,

([a-zA-Z])+|([\,\.])


匹配结果:

We 

can 

leave 

the 

Christmas 

lights 

up 

util 

January 

.


简写模式

那么问题来了,如果我们想要拿到所有符号呢

一个一个枚举不是我们工程师的丝带儿(style)

于是正则的简写模式来了


\d就是[0-9]。表示是一位数字。记忆方式:其英文是digit(数字)。

\D就是[^0-9]。表示除数字外的任意字符。

\w就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。

\W[^0-9a-zA-Z_]。非单词字符。

\s[ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。

\S[^ \t\v\n\r\f]。 非空白符。

.就是[^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号...中的每个点,都可以理解成占位符,表示任何类似的东西。


改写下([a-zA-Z])+|([.\,]),使它兼容所有符号

即 ([a-zA-Z])+|([\S.]),匹配除了换行符之外的所有单词和符号

为了测试,我们把样例改成We can leave the Christmas lights up , util January!


匹配结果:

We 

can 

leave 

the 

Christmas 

lights 

up 

util 

January 

!

现在你是不是可以稍微认同一下我的分类重要性的观念了呢~


位置匹配

如果我只是想要拿到最后一个单词呢,即January,该怎么做呢。

正则提供了关于字符串位置的符号:


^匹配输入字符串开始的位置

$匹配输入字符串结尾的位置

\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B与 \b 相反:er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。


先写出表达式,([a-zA-Z]+)(.)$ 即最后一个字符串加符号结尾的字符集


匹配结果:

January!


看到这里你可能会疑问,那我不要符号,我只要最后一个单词。

别急,String.prototype.replace结合我们的圆括号分组可以获得我们分组的单个变量

var pattern = /([a-zA-Z]+)(.)$/,  
str = 'We can leave the Christmas lights up, util January!';
str.replace(pattern,(a,b,c)=>{ 
    // a,b,c 为 January! January ! 
    return something
})复制代码

由于我们将匹配模式分成了两组,一组为单词,一组为符号,

所以replace的函数形参除了我们的匹配结果外,还多了两个值,即单词January和符号 !


结语

看了这么多,我相信基本的匹配已经难不倒你了。

在学习正则的过程中,上图截图里的工具是Regulex,它能非常好的帮你辨识你的查询范围是否正确。

同时配合正则表达在线测试工具验证是否匹配正确。

其实正则还有好多在本文里没有提到的功能,可以自行探索蛤。