前端正则入门

273 阅读4分钟
写在开头

平时你是怎么学习正则的?平时工作中用到多吗?是不是学了以后过一段时间就忘了?是不是用的时候都是”拿来主义“,对于复杂的并没有深入了解背后的原理?如果以上有命中你的,恭喜,你和我一样,都是普通人,对于正则都是头大一族。本文也不会带你飞,要深入学习还是你自己多琢磨,这里只是对于基本概念的讲解,学习一个技术点就是从概念入手,然后做几个练习,就算是入门了,最好举一反三,才是真正的学习之道。不啰嗦了,概念走起。

元字符
元字符 含义
^ 像一个帽子,从头开始,所以它思匹配一个字符串开始的位置
$ 像一个美元符,意思是最后才付款,匹配一个字符串的结束位置。
. 匹配除了换行符(\n,\r)之外的任何单个字符
\w 匹配字母、数字、下划线 我们可以这样表示[A-Za-z0-9_]
\W 与小写的w意思刚好相反,匹配非字母、数字、下划线
\d 匹配一个数字字符 等价于 [0-9]
\D 世界上事物总是相克的,所以它的意思是匹配一个非数字字符
\s 匹配任何不可见字符,包括空格、制表符、换页符。等价于[\f\n\r\t\v]
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]

以上只是一些主要的常见元字符,列举太多其实大家也记不住,要用的时候直接去查字典就好,当然常见的还是要记住,万一面试题要用到呢,你总不能查字典把。

量词

见明知义,就是跟数量有关系。

量词 含义
* 这个字符简直太常见了,它的意思是重复零次或更多次,等于{0,}比如/*.doc/ 匹配所有word文档。
重复0次或1次,等于{0,1}。
+ 重复1次或更多次,等于{1,}。
{n} 重复n次.
{n,} 重复n次或者大于n次
{n,m} 重复n次到m次.

工作中常用的几个也就上面几个,比如/^\d{5,12}$/表示5-12的数字。/^\w+/ 匹配一行的第一个单词

字符集

如果我们想匹配没有预定义元字符的字符集合,只需要在方括号里列举她们就行,就比如[abcd]或者[a-d]匹配a-d的字母,集合需要用省力的方式,比如[0-9]就和\d就是一样的意思,[A-Za-z0-9_]就等同于\w(这里是只考虑英文)。我们从一个匹配座机号码的表达式来分析,比如:

/\(?0\d{2}[) -]?\d{8}/

用图解的方式来看:

reg1.png

这个图用的是REGEXPER工具,我们很清楚的可以看出(出现0或者1次,然后后面接着个0,然后是接着两个数字,再就是) 空格和- 选其中一个,最后面就是接了8个数字。

####### 分支 分支的意思其实就跟我们平时代码分支有点类似的意思,有几种规则,如果满足其中任意一种规则都行,具体就是通过|字符把不同规则分隔开。比如说上面那个座机电话校验规则,我们不难发现011)12345678这样的格式也是能够匹配的,所以我们需要一个规则来区分前面有**"(",那么后面也要有")"**,所以我们在原有的基础上增加分支条件:

/\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}/

reg2.png

上图就清晰的看出,分为两条路径。我们需要特别注意的是:当使用|符号时,匹配规则是从左到右的,所以遇到满足的条件,就不会往后匹配了。

分组

我们前面了解到一个字符集合是通过[]包裹起来,那么想重复多个字符呢?我们可以通过小括号来指定子表达式,也就是所谓的分组,比如下面重复一组数

/([1-4]){1,3}/
反义

这个比较好理解,比如说除纯数字之外的字符 [^\d],元字符中有下列比较常见的几个反义字符。 | 元字符 | 含义

| \W | 匹配任意不是字母,数字,下划线,汉字的字符 | \D |世界上事物总是相克的,所以它的意思是匹配一个非数字字符 | \S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]

后向引用

这个概念理解起来比较耗脑,我们在一个表达式里面如果有分组捕获,那么从左到右依次顺序就是1,2,3...,比如说/(\d{4})-(\d{2})-\2/,这个表达式前面有两个分组,那么/2的意思是重复(\d{2})的匹配,那么字符串'4444-11-11'就能够满足匹配。我们来看下图解:

reg3.png

零宽断言(lookaround assertions)

也翻译成环视,根据方向的不同,分为lookahead和lookbehind,根据判定原则,分为肯定和否定;如下:

正向/预测先行/顺序/从左到右/pattern的前面的位置 负向/回顾后发/逆序/从右到左/pattern的后面的位置
肯定/正 (?=pattern) (?<=pattern)
否定/负 (?!pattern) (?<!pattern)

比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。需要特别注意的是:断言部分匹配为真的时候才会继续往下匹配,不然就截至了。

/(?<=<(\w+)>).*(?=<\/\1>)/.test('<a></a>')

仔细研究上面这个例子。

贪婪与懒惰
  1. 贪婪模式——在匹配成功的前提下,尽可能多的去匹配
  2. 惰性模式——在匹配成功的前提下,尽可能少的去匹配
  3. /.*bbb/g.test(‘abbbaabbbaaabbb1234’)
  4. /.*?bbb/g.test(‘abbbaabbbaaabbb1234’)
  5. 贪婪模式⽤于匹配优先量词修饰的⼦表达式
  6. 惰性模式⽤于匹配忽略优先量词修饰⼦表达式

懒惰限定符

代码/语法 说明
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

如果大神您想继续探讨或者学习更多知识,欢迎加入QQ或者微信一起探讨:854280588

QQ.png
微信