正则表达式案例分析 (二)
前言
最近在重新学习正则表达式,把在学习过程中所遇到的案例,还有比较难理解概念用自己的理解分析并整理总结。
如有哪些地方不对,欢迎指正,谢谢!(๑•ᴗ•๑)
本系列使用的JavaScript
所支持的正则表达式语法,并推荐你使用 regexr.com/ 去做相应的练习。
假定你已经熟悉元字符
,方括号
,修饰符
,量词
及RegExp对象
。
如果没有,请先看一遍文档
www.w3school.com.cn/jsref/jsref…
本系列同步GitHub github.com/Janking/Blo…
系列目录
正则表达式案例分析 (一)
案例分析
(1) 重复分组
在上一篇介绍千分位的时候,就有用到重复分组,这是一个很容易理解错误的点,至少我开始的时候是理解错误的。
假定用这个正则去匹配 1234567890
,开始我以为分组小括号(\d\d\d)
的最终结果是 123
,456
,789
都能拿到,但结果却只有789
重复分组的匹配在每次引擎退出该分组的时候被捕获,并会覆盖该分组在之前匹配的任何文本
模拟一下引擎工作的步骤:
1. 第一次匹配,捕获到 `123`,退出分组
2. 第二次匹配,捕获到 `456`, 覆盖上一次捕获的`123`,退出分组
3. 第三次匹配,捕获到 `789`,覆盖上一次捕获的`456`,退出分组
4. 退出重复分组,结束复制代码
因为重复分组最后一次循环存储的是789,另外两次分组匹配,也就是123,456是无法被获取的。
如果想要获得所有结果,就要把重复匹配放进分组中 /((\d\d\d){3})/
(2) 获取<p>...</p>
中的内容
/<p>(.*?)<\/p>/g.exec('<p>Hello,<em>world</em></p><p>Hello,Janking</p>')
运行结果
["<p>Hello,<em>world</em></p>","Hello,<em>world</em>", index: 0, input: "<p>Hello,<em>world</em></p><p>Hello,Janking</p>"
]复制代码
假如没有?
,而匹配结果就会差很远,不信你看!
/<p>(.*)<\/p>/g.exec('<p>Hello,<em>world</em></p><p>Hello,Janking</p>')
运行结果
["<p>Hello,<em>world</em></p><p>Hello,Janking</p>", "Hello,<em>world</em></p><p>Hello,Janking", index: 0, input: "<p>Hello,<em>world</em></p><p>Hello,Janking</p>"
]复制代码
缺少了问号?
,结果把中间的</p><p>
也匹配进来了,为什么一个字符不同,匹配结果就差异那么大?这里涉及到正则表达式中比较重要的概念:贪婪匹配,懒惰匹配,回溯
贪婪匹配
属于贪婪模式的量词,也叫做匹配优先量词,包括:{m,n}
,{m,}
,?
,*
和 +
。
惰性匹配
在匹配优先量词后加上?
,即变成属于惰性匹配的量词,也叫做忽略优先量词,包括:{m,n}?
,{m,}?
,??
,*?
和 +?
。
回溯
当前前面分支/重复匹配成功后,没有多余的文本可被正则后半部分匹配时,会产生回溯
用一个简单的例子来解释一下贪婪匹配和惰性匹配!
贪婪 : /\d+\b/
惰性 : /d+?\b/
文本 : 1234a
贪婪正则匹配 1234a
时的过程是这样的:
1. \d+ 匹配得到 12342. \b 却匹配失败,因为它的左边必须是数字,而不是字母 (\b 是分词边界匹配,用来获取位置,而不是文本,上一节有讲到)4. 这个时候,\d+会尝试回吐一个字符,即匹配结果为 123 ,可\b还是匹配失败!5. 那就继续回吐,一直到 1,还是匹配失败,那么这个正则就整体匹配失败了6. 这个回吐匹配结果的过程就是回溯复制代码
惰性正则匹配 1234a
时的过程是这样的:
1. \d+? 首先匹配,结果是 1 ,紧接着 \b 匹配失败2. 那就 \d+? 继续匹配,结果是 12 ,紧接着 \b 还是匹配失败3. \d+? 一直匹配到1234,紧接着的 \b 依然匹配失败4. 结果整个正则匹配不成功复制代码
通过这两个例子的比较,相信你会猜到回溯会影响匹配速度,回溯的过程慢那是相对那些DFA引擎。
而JS的正则引擎是NFA(非确定型有限自动机),匹配慢,编译快。
结束语
本章节将的案例只有两个,主要是涉及到几个重要概念,占了一定的篇幅,由于本人不喜欢把文章写的太长,影响阅读体验,所以就此打住,从下一篇开始会重点的去分析常用正则表达式的匹配过程,敬请期待。
参考文献:
- 《精通正则表达式》
- 《正则表达式经典实例》
转载于:https://juejin.im/post/5973f16c51882573c14a812d
正则表达式案例分析 (二)相关推荐
- 阿里Java学习路线:阶段 1:Java语言基础-Java面向对象编程:第21章:抽象类与接口应用:课时94:案例分析二(绘图处理)
案例分析二 考虑一个表示绘图的标准,并且可以根据不同的图形来进行绘制: interface IGraphical { // 定义绘图标准public void paint() ; // 绘图 } cl ...
- 英语专业转学计算机,转学案例分析二十二:英语专业转经济名校michigan
学生 S同学 就读院校 人大 标准化考试 TOEFL 102 SAT 1910 GPA 88/100 录取院校 U of Wisconsin Madison-Economics Penn State ...
- 集美大学1414班软件工程个人作业2——个人作业2:APP案例分析
一.作业链接 个人作业2:APP案例分析 二.博文要求 通过分析你选中的产品,结合阅读<构建之法>,写一篇随笔,包含下述三个环节的所有要求. 第一部分 调研, 评测 下载软件并使用起来, ...
- matlab软件及基础实验第8单元,《MATLAB统计分析与应用:40个案例分析》程序与数据(内含彩蛋)...
[实例简介]Matlab教材及随书光盘,超实用的好书,强烈推荐! MATLAB统计分析与应用 40个案例分析.pdf <MATLAB统计分析与应用:40个案例分析>程序与数据.rar 第1 ...
- 网络工程师--网络规划和设计案例分析(6)
案例:某企业网络拓扑如下图所示,中国电信和中国移动双链路接入,采用硬件设备实现链路负载均衡,主磁盘阵列的数据通过备份服务器到备份磁盘阵列,根据下图分析相关问题: 案例分析一:根据上图进行分析: 1.设 ...
- matlab案例分析总结,MATLAB统计分析与应用:40个案例分析
第章编程简介 1.1MATLAB工作界面布局与路径设置 1.1.1MATLAB工作界面布局 1.1.2MATLAB路径设置 1.2变量的定义与数据类型 1.2.1变量的定义与赋值 1.2.2MATLA ...
- 网络工程师--网络规划和设计案例分析(7)
案例一:某企业组网方案如下图所示,网络接口规划如下面表格所示,公司内部员工和外部访客均可通过无线网络访问企业网络,内部员工无线网络的SSID为Employee,访客无线网络的SSID为Visitor ...
- linux 进入gedit命令,linux中gedit命令报错的案例分析
linxu下的gedit命令相信大家都很熟悉,但是这么简单的命令也经常会报错.下面由学习啦小编为大家整理了linux的gedit命令的报错案例分析相关知识,希望对大家有帮助! linux中的gedit ...
- 软考高级-系统架构师-案例分析-架构设计
本篇博文目录: 考点分析 一.软件架构风格 1.基本概念 2.真题案例分析 二.质量属性与架构评估 1.基本概念 2.案例分析 三.Web架构综合考查 1.Web服务器技术演变 (1) 负载均衡技术 ...
- Python爬虫_案例分析(二)
Python爬虫_案例分析(二) 一.电影天堂案例 import scrapy from scrapy_movie.items import ScrapyMovieItem class MvSpide ...
最新文章
- 视频直播营销时代已来,企业该如何把握这波红利?
- 商品类型的下拉框绑定一个事件,通过ajax获取属性
- C++ static的作用
- strtus2改成springboot_springboot+struts2打成jar包运行
- notepad++每行首尾添加内容
- 用心整理,1000行MySQL命令,很实用,建议收藏
- CSS和JS两种颜色渐变文字效果代码
- 技术人解读企业为什么要平台化,关于数据中台你不知道的事...
- springboot中使用@Value读取配置文件
- 登录 Unix 操作系统
- 【大学物理】设计性实验报告
- 如何让计算机自动重启,教你如何实现让win7系统电脑定时自动重启
- UE4:浅谈什么是GamePlay框架
- SpringBoot--任务:邮件任务
- java构造方法是什么_java中什么叫构造方法,作用是什么?
- javaWeb基础一:JDBC (java操作数据库的技术)
- 查看电脑连接过的所有无线的密码
- trunk接口(华为)新手必看
- mPEG-Tert 甲氧基PEG叔丁酯
- python培训视频课程学习路径