正则一文通

0x000 概述

正则是用来搜索字符串的!!!
正则是用来搜索字符串的!!!
正则是用来搜索字符串的!!!

重要的事儿说三遍,这个是这片文章的结论。

0x001 环境介绍

  • 主要示例语言:javascript
  • 实验场地:Chrome Console
  • 主要函数:str.match(regexp)

    • 示例:
      正则一文通_第1张图片
    • 参数:regexp
      一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。如果你未提供任何参数,直接使用 match() ,那么你会得到一个包含空字符串的 Array :[""] 。
      以上太官方了,这个参数直接传入一个正则表达式就行了(上图中的栗子2),当然传一个普通的字符串也行(上图中的栗子1),会自动转化的。如示例所见,完成的功能就是在helloworld字符串中搜索h字符而已。
    • 返回值:array
      如果字符串匹配到了表达式,会返回一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果。如果没有匹配到,返回null
      以上太官方了,匹配到就返回结果数组,没匹配到返回null,具体的结果视表达式的不同而有区别,现在讲了也感受不到。上面的例子中键0的返回值就是搜索到的结果。
    • 关于该函数详细说明和具体用法,可以查询 MDN,不过现在没有必要就是了。
    • 正则写法:

      • //:在两个/之间写,推荐这种方式,这种方式下,两个/之间不能什么都不写,因为会发生很神奇的事情--会变成注释符号,导致后面的语法错误...
      • 直接写字符串:会自动转化,但是和第一种方式有些微妙的不同,推荐第一种
  • 说明:以下的标题只是我归纳出来的结果,在正则中并不是如此叫法。

0x002 普通字符

实用性技能的学习还是从实际需求出发比较好,在字符串搜索的应用场景中,最常见的需求是啥?就是在字符串中搜索是否包含另一个字符串

例如在helloworld中判断是否有h,或者是否有hello,在这种情况下,就使用所有为的普通字符就好了,这种情况下,就起到了和indexOf一样的功能,所以我们现在我们可以用正则完成在字符串中搜索是否包含另一个字符串的需求了。

正则一文通_第2张图片

但是如果正则只能做到这样,那还不如直接用indexOf,还学啥正则,在上面的栗子中,我们所要搜索的字符串是已知的确定的,比如我们知道我们要搜索hhello,这些都是已知的确定的,但是在很多场景中,我们要搜索的是不确定的只满足一定规则的。所以就有了格式校验

0x002 替代符

格式校验通常出现在表单应用中,比如注册需要填写账户和密码,而账户和密码需要满足一定的条件,账户必须是邮箱、密码必须6-16位字母和数字组合等。

这里就出现了对不确定的只满足一定规则的的字符串的搜索,只要有搜索结果,则就校验通过,无结果,校验则不通过。

如何做到呢,那就是替代符替代符可以替代某一种类型的字符,比如数字、字母、回车、换行等等等。

替代符的格式是普通字符前面加\,比如\d\w等,为啥要加\呢,因为不加\就是普通字符了啊。

  1. 替代一个数字:\d

    clipboard.png
    说明:可以完成需求:字符串中是否至少包含一个数字,这里的数字指的是:01234567890

  2. 替代一个非数字:\D

    clipboard.png
    说明:可以完成需求:字符串中是否完全不包含数字,这里的数字指的是:01234567890

  • 替代一个字符:\w

    正则一文通_第3张图片

    说明:可以完成的需求:字符串中是否至少包含一个字符,这里的字符指的是:1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmnopqrstuvwxyz_,或者0-9A-Za-z_

  1. 替代一个非字符:\W

    clipboard.png

    说明:可以完成的需求是:字符串是否完全不包含字符,这里的字符指的是:1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjklmnopqrstuvwxyz_,或者0-9A-Za-z_

  2. 替代一个换行符:\n:

    正则一文通_第4张图片
    说明:可以完成的需求是:字符串是否包含至少一个换行符

  3. 替代一个制表符:\t:

    clipboard.png
    说明:可以完成的需求是:字符串是否包含至少一个制表符,这里的制表符指的是按Tab键产生的

  4. 替代任意一个空白字符:

    正则一文通_第5张图片
    说明:可以完成的需求是:字符串是否包含至少一个空白字符,这里的空白字符指的是换行符空白符制表符

  5. 替代任意一个非空白字符:

    正则一文通_第6张图片

     可以完成的需求是:`字符串是否完全不包含空白字符`,这里的空白字符指的是`换行符`、`空白符`、`制表符`等
  6. 匹配\n之外的任何字符:.

    正则一文通_第7张图片

将以上的几种替换符结合起来,我们就可以完成一些比较有意思的事了,比如:

  • 是否包含指定长度的数字:

    clipboard.png

  • 密码是否都是字符:

    clipboard.png
    说明:栗子1返回null说明校验通过了,栗子2返回了搜索结果,说明存在非字符,所以校验不通过。

虽然可以做到这种程度,但是依旧不够,比如我们无法限制长度,或者更精细的控制,比如邮箱格式的限制,匹配连续10000个0等。以abc100000@qq.com为例,可以看出,邮箱的规则大概是

  • 开头以多个字母或者数字组成
  • 包含@符号
  • @后面是一个域名。
  • 域名又有自己的规则:

    • 开头以多个字母或者数字组成
    • 包含.
    • .后面以多个字母或者数字组成

邮箱的格式校验已经怎么复杂了,更何况如果我们要限定指定的几个域名呢?所以任重而道远啊,还得接下去学

0x003 数量

我们在0x002中已经可以做到对数量的控制了,即/\d\d\d/这种形式,但是这种形式是有问题的,如果我们要匹配10000个0呢,写10000个/d可不现实,所以这里必须引入新的符号,那就是数量

  1. 匹配前一个表达式0次或者多次:*

    正则一文通_第8张图片
    说明:注意,这里说的是表达式,目前先当做字符来理解,意思是匹配o这个字符0次或者多次

  2. 匹配子表达式1次或者多次:+

    正则一文通_第9张图片
    说明:匹配o这个字符1次或者多次

3 匹配字表达式0次或者1次:?

![clipboard.png](/img/bVbd8Cu)

**说明**:匹配`o`这个字符0次或者1次
  1. 匹配指定次数:{n}n为次数

    正则一文通_第10张图片
    说明:匹配o这个字符n

  2. 匹配最少几次:{n,}n为次数

    正则一文通_第11张图片
    说明:匹配o这个字符至少n

  3. 匹配最多几次:{n,m}n为最少的次数,m为最多的次数
    正则一文通_第12张图片
    说明:匹配o这个字符 n-m

到目前为止,完成了普通字符替代符数量,那我们可以做的事情可就多了,比如邮箱格式校验


![clipboard.png](/img/bVbd8El)

但是,依旧存在问题,请看下面


![clipboard.png](/img/bVbd8Ew)

我们在邮箱前面和后面加了空白符和其他符号,通过了校验,这很明显是我们目前无法解决的,继续往下

0x004 限定

  1. 指定开头字符:^

    正则一文通_第13张图片

  2. 指定结尾:$:

    正则一文通_第14张图片

  3. 继续邮箱校验:
    clipboard.png
    目前看似没问题,但是如果我们要求只能使用gmailqq登录呢?还得往下啊!

0x005 运算符

  1. 集合:[]
    clipboard.png
    说明:不包含abc中的任意字符

  2. 字符范围:[a-z]

    clipboard.png
    说明:包含a-z0-9

  3. 或:|

    正则一文通_第15张图片
    说明:是否包含a或者b

0x006 子表达式

字表达式使用()来表示,()内为一个整体。
直接上栗子:

  • 邮箱验证:

    正则一文通_第16张图片
    说明:匹配gmail或者qq

  • 获取满足某种格式的数据,比如获取文章中的电话号码

    正则一文通_第17张图片
    说明:其中:1是整个表达式/tel:(\d+)/的结果,2是子表达式\d+的结果

在正则中,所有的单个匹配都是子表达式,比如aa+a{n,m}等。所以,其实这包含一种递归的思想,所以,所有使用在表达式上的都可以使用在这些之上,比如(ab)+,可以匹配ababab

0x007 总结

正则表达式的作用就是

搜索字符串!!!
搜索字符串!!!
搜索字符串!!!

只不过可以搜索不确定的满足某种规则的的字符串,而这个功能可以引申出多种使用场景

  • 字符串搜索
  • 格式校验
  • 字符串截取

0x008 参考材料:

你可能感兴趣的