点击上方“”,选择加""或“”
重磅干货,第一时间送达
至于正则表达式,我一直用得很浅,一直想好好学习。今天分享的文章仔细梳理了正则表达式的各个方面,甚至思维导图和动图,与大家分享
剧照 | 《想见你》
来源:猪哥@裸睡的猪
目前,越来越多的网站、编辑器和编程语言支持一种叫做”的字符串查找“公式”,有过编程经验的同学都应该了解(Regular Expression 简写regex)什么是字符串匹配模式?(pattern),更像是逻辑公式。
使用正则表达式匹配字符串Hello World 中的 Hello 伪代码:/Hello/, "Hello World" 输出:Hello
如何写一篇关于的文章 我想了一个星期的文章,从来没有一篇文章能让猪哥这么麻烦。
因为我觉得 :难以记忆,难以描述,广泛而深刻,不受重视。有人说正则表达式既容易写又难写!
:无非是写一些常用实用的案例。说实话,你们每个人都可以写这个:在网上百度,结合自己的实际经验,一篇文章就出来了。
:很多人认为正则很简单,不用记住,想用百度。但绝大多数人只知道正则的一小部分,但真正的本质很少被关注!
猪哥希望你能知道有很多正则知识点,尤其是,这是正则表达式的高级知识点,也可能在面试中被问及。
当我们学习一门技术时,有必要了解它的起源和发展过程,这有助于我们了解技术本身!
:正则表达式的最初想法来自两位神经学家:沃尔特·皮茨和麦卡洛克开发了一种数学描述的模型。
:一位名叫Stephen Kleene数学科学家发表了一篇题为《神经网事件表达法》的论文,称之为,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“这个术语。
:C语言之父、UNIX之父这种正则表达式的理论结果用于一些搜索算法的研究。他描述了一种正则表达式编译器,因此出现了最早的正则表达式编译器qed(这也成了后来grep编辑器)。
Unix使用正则后,正则表达式不断发展壮大,然后广泛应用于各个领域。根据这些领域各自的条件和需要,开发了许多版本的正则表达式和许多分支。我们称这些分支为”。
:Perl语言诞生了,它结合了其它语言,以正则表达式为基础,创造了一个新的流派,。许多编程语言如:。
在这里我们也知道。
注:Perl语言是一种擅长处理文本的语言,但许多开发者不喜欢它,因为模糊的语法和奇怪的符号不利于理解和记忆。
ps:元字符表示正则表达功能的最小单位,如 *
^
$
\d
等等
关于语法部分猪哥不想解释太多,给你一个详细的总结,让你以后快速找到!
如果你想系统地学习正则表达式的语法部分,猪哥推荐 https://www.runoob.com/regexp/regexp-tutorial.html
匹配原理是猪哥想重点讲解的部分,也希望同学们能认真理解这部分。
很多人认为没有必要了解汽车的结构原理,但我们真的需要了解编程的原理。
只有了解原理,你才能,这往往是初级工程师和中高级工程师的区别之一!
1.执行过程
正则表达式的执行,是由正则表达引擎编译执行的,大致的执行流程猪哥也画了个流程图给大家看看。
这里给大家提一点:
猪哥,为什么呢?
以Python语言内置re
模块举例:
通过
re.compile(pattern)
预编译返回,可直接引用后代码。通过
re.match(pattern, text)
即使是编译,也会有缓存,但每次使用都需要在缓存中取出,比预编译多一步。
猪哥也通过实际测试
pattern = r'http:\/\/(?:.?\w ) ' text = '<a href="http://www.xxx.com">xxx.com</a>'
2.发动机(重点)
由于正则表达式是由执行引擎执行的,我们来谈谈正则表达式引擎,,希望大家仔细看看,理解!
正则引擎可分为两类:
ps:当然,还有种引擎是:POSIX NFA,这是根据NFA引擎的标准版本,但由于使用较少,我们在这里不重点解释。
在这里,我需要向你解释什么是什么确定型
、有穷
、自动机
这些名词:
:假设有字符串(text=abc)需要直接匹配,不写正则表达式,不能确定字符匹配顺序的是不确定型。
:贫穷意味着有限,这意味着结果可以在有限的时间内得到。
:自动机是由发动机自动完成的,我们设置匹配规则后,不需要人为干预!
根据以上解释,我们可以知道:字符执行顺序是否可以在不写正则表达式的情况下确定!
为了让每个人都能清楚地理解DFA发动机执行原理,猪哥做了一个简单的动态执行过程图给大家看我们可以根据上面的动图得到它DFA发动机的一些特点:
:按照文本的顺序执行可以解释为什么DFA发动机是确定型(deterministic)了,稳定!
记录当前有效的所有可能:我们看到当执行到 (d|b)
时,同时比较表达式中的d
和b
,所以会需要更多的内存。:这提高了执行效率,而且速度与正则表达式无关。
:因为每个字符只检查一次,文本零宽度(位置)只记录当前比较值,所以不能使用反向引用、环视等一些功能!
猪哥同样画了一个简易的NFA引擎执行过程图方便大家理解根据上面的动图我们可以得出NFA引擎的一些特点:
:按照表达式的一部分执行,如果不匹配换其他部分继续匹配,直到表达式匹配完成。
:我们看到当执行到
(d|b)
时,NFA引擎会记录字符的位置(零宽度),然后选择其中一个先匹配。:我们看到当执行到
(d|b)
时,比较d
后发现不匹配,于是NFA引擎换表达式的另一个分支b
,同时文本位置,重新匹配字符'b'。这也是NFA引擎是非确定型的原因,同时带来另一个问题效率可能没有DFA引擎高。:因为具有这一步,所以可以很容易的实现反向引用、环视等一些功能!
关于这两种引擎的总结,猪哥引用《精通正则表达式》书本中的一句话来概括:
DFA(电动机) 和NFA(汽油机) 都有很长的历史,不过,正如汽油机一样,NFA 的历史更长一些。也有些系统采用了混合引擎,它们会根据任务的不同选择合适的引擎(甚至对同一表达式中的不同部分采用不同的引擎,以求得功能与速度之间的最佳平衡)。 ——《精通正则表达式》
3.回溯(重点)
作为绝大多数编程语言都选择的引擎——NFA (非确定型有穷自动机) 引擎,我们当然要再详细了解一下。动图中,我们可以看到当某个正则分支匹配不成功之后,文本的位置需要回退,然后换另一个分支匹配,。
回溯的原理类似我们走迷宫时走过的路设置一个标志物,如果不对则原路返回,换另一条路。
回溯机制不但需要重新计算和的对应位置,也需要(b匹配成功),保存到内存中以数字编号的组中,这就叫。
保存括号内的匹配结果之后,我们在后面的正则表达式中就可以使用,这就是我们所说的,在上面的案例中只有一个捕获,所以$1=b
。
:讲到回溯必须提到回溯陷阱,它导致的结果就是机器CPU使用率爆满(超100%),机器就卡死了。
举个例子:text=aaaaa,pattern=/^(a*)b$/,匹配过程大致是
(a*):匹配到了文本中的aaaaa
匹配正则中的b,但是失败,因为(a*)已经把text都吃了
这时候引擎会要求(a*)吐出最后一个字符(a),但是无法匹配b
第二次是吐出倒数第二个字符(还是a),依然无法匹配
就这样引擎会要求(a*)逐个将吃进去的字符都吐出来
但是到最后都无法匹配b
这里的重点就在于 引擎会要求*
匹配的东西一点一点吐回,我们假设如果文本长度为几万,那引擎就要回溯几万次,这对机器的CPU来说简直是灾难。
有些复杂的正则表达式可能有多个部分都要回溯,那回溯次数就是指数型。如果文本长度为500,一个表达式有两部分都要回溯,那次数可能是500^2=25万次,这谁受得了!
关于更多更详细的回溯介绍,推荐大家可以阅读《精通正则表达式》这本书!
编写巧妙的正则表达式不仅仅是一种技能,而且还是一种艺术。
上面我们了解到,,而NFA引擎的特点是:、但有回溯机制所以。所以我们需要学习一些NFA引擎的一些优化技巧,以以及更直接的匹配到结果!
针对NFA引擎的可优化的点其实挺多的,为了方便大家记忆,猪哥也画幅结构图归纳一下,方便大家收藏细看。在面试过程中也许会被问到关于正则的优化,大家记住几点就可以。
上面我们讲解了关于正则表达式的诞生和发展、引擎、优化等知识,但是关于正则表达式的知识点远远不止这些,所以最后猪哥推荐一些好的学习资料,大家有空可以了解学习下。
1.书
推荐正则表达式的书,那必然是《精通正则表达式》 ,目前这本书已经出了第三版,豆瓣评分8.9。
内容虽然稍有啰嗦,但是对于正则新手很友好,唯一不足是Python案例少。
2.博客
入门:菜鸟教程:https://www.runoob.com/regexp/regexp-tutorial.html深入:某不知名大佬:https://blog.csdn.net/lxcnn
3.在线测试工具
https://regex101.com/,这个网站可以选择不同编程语言的正则支持,有语义分析、匹配测试、参考列表等,非常实用。
4.常用案例
一些简单常用的小案例汇总,菜鸟教程:http://c.runoob.com/front-end/854
最后祝愿大家都能搞定正则表达式,处理文本可以得心应手!
在「」公众号后台回复:即可下载全网第一份OpenCV扩展模块教程中文版,涵盖等二十多章内容。
在「」公众号后台回复:即可下载包括等31个视觉实战项目,助力快速学校计算机视觉。
在「」公众号后台回复:即可下载含有个基于实现20个,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。在群内发送广告,否则会请出群,谢谢理解~