美文网首页
js正则 控制权与传动

js正则 控制权与传动

作者: 项布斯 | 来源:发表于2020-05-05 14:01 被阅读0次

写这篇文章的目的一是记录,二是想把自己的领悟整理分享给大家,好让大家了解一下正则表达式到底是如何进行匹配的。这篇文章可能不会很系统的去讲js(毕竟也没那样的能力),就简单分享一下我对正则控制权和传动的理解。话不多说,进入正题。(ps:这篇文章适合有一定js正则基础的人阅读)

1  正则眼中的字符串和位置

在讲控制权和传动之前,了解正则眼中的字符串和位置对理解正则表达式很有用。

上图中一共有8个字符,9个位置,在正则中位置也是可以匹配的,比如^匹配字符串开始位置,$匹配字符串结束位置,它仅仅匹配的是位置,匹配结果中不会出现。同时位置的匹配不是互斥的,即同一个位置可以匹配多次,但字符的匹配是互斥的,只能匹配一次。

2 控制权与传动

了解了正则的位置和字符的概念,理解控制权与传动就容易多了。

控制权是指哪一个正则子表达式(可能为一个普通字符、元字符或元字符序列组成)在匹配字符串,那么控制权就在哪。

传动是指正则引擎的一种机制,传动装置将定位正则从字符串的哪里开始匹配。

正则表达式当开始匹配的时候,一般是由一个子表达式获取控制权,从字符串中的某一个位置开始尝试匹配,一个子表达式开始尝试匹配的位置,是从前一子表达匹配成功的结束位置开始的。

举一个栗子,read(?=ing)ing\sbook匹配reading book,我们把这个正则看成5个子表达式read、(?=ing)、ing、\s、book,当然你也可以吧read看做4个单独字符的子表达式,只是我们这里为了方便这么看待。read从位置0开始匹配到位置4,后面的(?=ing)继续从位置4开始匹配,发现位置4后面确实是ing,于是断言匹配成功,也就是整一个(?=ing)就是匹配了位置4这一个位置而已(这里更能理解什么是零宽了吧),然后后面的ing再从位置4开始匹配到位置7,然后\s再从位置7匹配到位置8,最后的book从位置8匹配到位置12,整一个匹配完成。

3 几个实例

我们再用实际栗子验证一下我们的理解。

栗子1:

‘123456789’.replace(/\B(?=(\d{3})+$)/g,','); // 123,456,789

咋一看到这个表达式属实会有点晕,没关系我们一层层来剥开它的外衣。首先需要知道表达式中的一些元字符代表什么意思。\B 匹配的是非单词边界,就比如abc,从位置0开始匹配,位置0是单词边界,匹配不上,匹配到位置1的时候发现是非单词边界,匹配上了,匹配就结束了,所以匹配的就是位置1。在表达式(\d{3}+$) 中,$匹配结束位置,\d 匹配数字,\d{3}, 匹配3个数字,\d{3}+ 则匹配 一个或者多个\d{3} ,连起来就是匹配以3个或者3个数字的倍数为结尾的字符串的位置。(?=xx) 是正向零宽断言,表示后面只能跟xx表达式,注意正向零宽断言也是匹配位置的。/g表示全局匹配。到这整个表达式就分析完了。概括起来整个正则就是用来匹配 非单词边界开头且以3个或者3个数字的倍数为结尾的字符串的位置。很绕吧,但是就是这么神奇,不匹配具体的字符,就是用来匹配位置的。下面再用控制权和传动分析一下具体的匹配过程。

正则表达式 /\B(?=(\d{3})+$)/g 

字符串 123456789

1 第一轮匹配,首先由\B子表达式获得控制权,匹配位置0,位置0是单词边界,匹配不上,位置传动到位置1,位置1是非单词边界符,匹配成功。

2控制权交给子表达式 (?=(\d{3})+$) ,上面分析过了,这个表达式是用来匹配以3个或者3个数字的倍数为结尾的字符串的位置。位置1 后面跟的是23456789,不是3的倍数,匹配不上,传动位置到位置2,位置2后面跟的是3456789,依旧不满足,再次传动到位置3,位置三后面跟的是456789,匹配成功,也就是位置3满足条件,匹配成功。第一轮匹配结束。

3 第二轮匹配,控制权再交给\B子表达式,此时匹配就从位置4开始匹配,位置4匹配成功,再重复步骤2,位置6匹配成功,因为位置6后面跟的是789,第二轮匹配结束。

4第三轮匹配,控制权再交给\B子表达式,此时匹配就从位置7开始匹配,位置7匹配成功,再重复步骤2,因为位置7后面跟的是89,子表达式 (?=(\d{3})+$)匹配失败,至此正则匹配结束。

匹配的结果是位置3和位置6。所以123456789才会变成123,456,789

栗子2:

正则表达式/\w+?\d+/g

匹配字符串aa11bb22c3d4e5f6

匹配结果aa11 bb22 c3 d4 e5 f6

这个栗子我们就简单分析一波。

1 首先\w+? 获得控制权,量词后面跟?表示非贪婪模式,\w匹配字母、数字、下划线,\w+匹配1个或多个\w, \w+?就是尽可能少的匹配\w。首先匹配位置0,位置0后面是a,基于非贪婪模式,匹配一个a即可,位置传动到1,控制权交给\d+,位置1后面是还是a,匹配失败,正则回溯到位置0,控制权再交给\w+?,这时\w+?知道匹配一个a是不够的,所以会匹配两个a,此时位置传送到位置2,控制权交给\d+,\d+ 贪婪匹配多个数字,即匹配11,位置传送到位置4,aa11匹配成功,第一轮匹配结束。控制权再交给\w+?,如此循环往复,依次匹配出bb22 c3 d4 e5 f6。

小案例蕴含大智慧。

至此,js正则的控制权和传动就告一段落了,其中案例二中用到了回溯的概念,欢迎批评和指正,另外有正则的问题也可以留言探讨,交流才能进步,固步自封永远也无法突破知识盲区。

更详细的内容请移步:

https://www.jb51.net/article/110516.htm?winzoom=1

本文是参考这遍文章书写的,后面的案例也是之前某些地方遇到的,随手拿来分析一波。

分享一个js正则表达式校验的网站:https://regex101.com/r/DAcXTU/2,本文的案例都可以在此网站上进行测试。

相关文章

  • js正则 控制权与传动

    写这篇文章的目的一是记录,二是想把自己的领悟整理分享给大家,好让大家了解一下正则表达式到底是如何进行匹配的。这篇文...

  • 什么是液体传动、液力传动与液压技术?

    什么是液体传动、液力传动与液压技术? ①以液体为工作介质进行能量传递、转换与控制的传动方式称为液体传动。按其工作 ...

  • 什么是液体传动、液力传动与液压技术?

    什么是液体传动、液力传动与液压技术? 1.以液体为工作介质进行能量传递、转换与控制的传动方式称为液体传动。按其工作...

  • 正则初解

    title: js验证常用正则表达式date: 2017-03-03 验证 正则表达式 本文介绍js验证常用的正则...

  • JS正则表达式

    JS正则表达式一条龙讲解,从原理和语法到JS正则、ES6正则扩展,最后再到正则实践思路 Stinson 关注 20...

  • 正则表达式和Node.js

    正则表达式:创建正则表达式的两种方式;正则表达式的常见用法;正则与数值和其它注意事项 Node.js :什么是No...

  • 正则详解--程序员必备

    转自: JS正则表达式一条龙讲解,从原理和语法到JS正则、ES6正则扩展,最后再到正则实践思路 温馨提示:文章很长...

  • 前端学习资源整合(二)

    正则 正则 地址JS正则表达式元字符 http://segmentfault.com/a/119000000247...

  • 学习资料

    js相关 阮一峰JS教程 阮一峰es6教程 JS原型与闭包 正则表达式 canvas学习 插件库相关 babel ...

  • JS基础

    JS基础 JS运算 JS代码块 JS对象 原型对象 GC 正则表达式

网友评论

      本文标题:js正则 控制权与传动

      本文链接:https://www.haomeiwen.com/subject/uiqmghtx.html