正则表达式regex回溯分析
正则表达式的回溯
现在我们来正式认识一下回溯。以字符串“abbc”为例,正则表达式为“ab{1,3}c”,再匹配的时候,a、b、b,匹配完成,这时候,正则表达式会继续用c和b进行比较,发现不符合,这时候就会产生回溯,也就是重新用c继续和正则表达式中的c进行比较,发现匹配成功,后续没有需要匹配的字符,完成匹配。
我再把例子变一下,假设正则表达式还是“ab{1,3}c”,但是字符串变为“abbabc”,这时候,还是和上面一样,只不过再匹配到a、b、b后,匹配a发现与b(因为b可以是1到3个)不符合,这时候产生回溯一位,a继续与c比较,发现仍不匹配,这时候会直接回溯到最前面,即字符串中的第二个字符b再重新与正则表达式开始匹配,这时候的回溯位数就比较多了。
正则表达式的贪婪、懒惰和独占
上面举的例子,为什么已经匹配到b了,还要继续匹配b而不是直接匹配c了呢,这就是因为正则匹配默认是贪婪模式,也就是希望尽可能多的去匹配字符,所以正则表达式中写的b的个数为1到3个,那么它就会尽可能取匹配3个,不行才是2个,再不行才是1个。
懒惰模式,就是尽可能少的匹配字符,所以上面那个例子会从1个b尝试,然后那c取匹配第二个字符,发现c与b不匹配,则回溯一位,用b{1,3}里的第二个b去匹配,然后接着再用c去匹配后面的字符。关键符号是“?”,即正则表达式变为“ab{1,3}?c”
独占模式,正则表达式会尽可能长的进行匹配,一旦匹配错误也不会进行回溯。上面的例子来说,再b{1,3}这部分的时候,他会一次把后面最多3个b拿出来,但是后面只有两个b了,所以它也只能拿两个,结束后再进行c的比较,匹配成功。关键符号是“+”,即“ab{1,3}+c”。这里举个例子,如果正则表达式变为“ab{1,3}+bc”,这里正则表达式的区别是后面多了个b,由于独占模式b{1,3}的部分会尽可能多的匹配,所以b{1,3}会把文本中的两个b都匹配了,则后面继续匹配,b不等于c,由于独占模式也不回溯,所以匹配失败了。(这里如果没有“+”号的话,是会产生回溯可以匹配成功的)
总结
这里推荐一个验证正则表达式的网站:https://regex101.com/,他除了可以检查正则表达式的正确性以外,还能给出匹配步数,并且可以解析出正则表达式的解析步骤(右上角的EXPLANATION),还有更详细的匹配过程(左下角的regex debugger),还有很多例子regex,非常好用。
最后还是给大家举个可能产生回溯陷阱的例子更容易理解吧。一般很多正则都会产生回溯,可能有个几十几百的步数还算正常,但是会产生回溯陷阱的一般都是无法匹配出来的,步数可能上完甚至几十万。正则表达式为“^(([a-zA-Z0-9]+).)+$”,字符串我就随便粘了一段比较长的网址,检测的就是字符串中是否是xxxx~xxxx|这种形式,就是一段[a-zA-Z0-9]字符串中间都要只有一个非[a-zA-Z0-9]的字符,如果有连续两个非[a-zA-Z0-9]的字符的话则匹配失败。(字符串举例“abcdekibana.xxxx.com/app/kibana#/discover/6530ca70-7467-11e8-8473-d1a78e1cb8f0?_g=(refreshInterval:('$$hashKey':'object:6533',display:Off,pause:!f,section:0,value:0),time:(from:now%2Fd,mode:quick,to:now%2Fd))&_a=(columns:!(vfdg,khg,tery,fgdg,fgdfs),filters:!(),index:fghyu98-6f97-11e8-be20-871a42a4e49a,interval:auto,query:(language: lucene,query:'dfgr:fjsdiouion7ee3%3D%3D'),sort:!('@timestamp',desc))”)
通过上面提到的验证网站,会发现产生“Catastrophic Backtracking”提示,点开regex debugger就能看到回溯情况了。
其实正则表达式大家用的很多了,一般用来检验用户名、邮箱、包含字符、url合法等。尤其是对于复杂的正则表达式来说一定要注意到使用的场景与具体回溯情况,如果会产生频繁回溯的正则表达式,那么就会掉入回溯陷阱,导致cpu飙高,严重回溯陷阱可能需要占用非常多的cpu时间,导致进程因为正则验证而假死,这点需要格外注意。
正则表达式regex回溯分析的更多相关文章
- C#正则表达式Regex常用匹配
使用Regex类需要引用命名空间:using System.Text.RegularExpressions; 利用Regex类实现验证 示例1:注释的代码所起的作用是相同的,不过一个是静态方法,一个是 ...
- C#正则表达式Regex类的用法
C#正则表达式Regex类的用法 更多2014/2/18 来源:C#学习浏览量:36891 学习标签: 正则表达式 Regex 本文导读:正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串, ...
- C#正则表达式Regex类
C#正则表达式Regex类的使用 C#中为正则表达式的使用提供了非常强大的功能,这就是Regex类.这个包包含于System.Text.RegularExpressions命名空间下面,而这个命名空间 ...
- (四)boost库之正则表达式regex
(四)boost库之正则表达式regex 正则表达式可以为我们带来极大的方便,有了它,再也不用为此烦恼 头文件: #include <boost/regex.hpp> 1.完全匹配 std ...
- boost 正则表达式 regex
boost 正则表达式 regex 环境安装 如果在引用boost regex出现连接错误,但是引用其他的库却没有这个错误,这是因为对于boost来说,是免编译的,但是,正则这个库 是需要单独编译 ...
- 请写出正则表达式(regex),取得下列黄色部分的字符串 TEL: 02-236-9655/9659 FAX:02-236-9654 (黄色部分即02-236-9655/9659 ) ( 测试面试题)
请写出正则表达式(regex),取得下列黄色部分的字符串 TEL: 02-236-9655/9659 FAX:02-236-9654 答: package test1; import java.uti ...
- Python 正则表达式(RegEx)
版权所有,未经许可,禁止转载 章节 Python 介绍 Python 开发环境搭建 Python 语法 Python 变量 Python 数值类型 Python 类型转换 Python 字符串(Str ...
- 正则表达式(RegEx)官方手册/权威指南【Python】
前言 正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的.高度专业化的编程语言,可通过 re 模块获得. 使用这种小语言,你可以为要匹配的可能字符串集指定规则:此 ...
- C#正则表达式Regex类使用
作为文本处理的利器——Perl语言对正则表达式的最强大支持起到了重要的作用,正因为如此,许多其他语言在加入正则表达式引擎的时候都会或多或少的兼顾perl风格的正则表达式,开发出相应的引擎.本人使用pe ...
随机推荐
- 2020年算法设计竞赛 DP
链接:https://ac.nowcoder.com/acm/contest/3002/I来源:牛客网https://ac.nowcoder.com/acm/contest/3002/I 题目描述 & ...
- EQ实现
原理参考: https://www.cnblogs.com/fellow1988/p/9189338.html https://www.cnblogs.com/fellow1988/p/9136346 ...
- 结合sqlmap进行sql注入过程
结合sqlmap进行sql注入:(-r后面是通过burp suite抓出来的请求包:-p后面是注入点,即该请求里携带的某个参数) Get请求的注入: ./sqlmap.py -r rss_test.t ...
- python文件读取:遇见的错误及解决办法
问题一: TypeError: 'str' object is not callable 产生原因: 该错误TypeError: 'str' object is not callable字面上意思:就 ...
- shiro登录认证过程讲解
先粘出登录的代码 1. 可以看到已经获取到了username和password ,为了接下来的认证过程,我们需要获取subject对象,也就是代表当前登录用户,并且要将username和passw ...
- 【转载】C++面试题(51-100)
转自:http://www.jobui.com/mianshiti/it/cpp/5018/ 51. 引用与指针有什么区别? 答 .1) 引用必须被初始化,指针不必. 2) 引用初始化以后不能被改变 ...
- Redis如果内存满了怎么办?
Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...
- CSS input
去除激活 input 的默认边框 // 三种方法都能实现 input{ outline: none; outline: medium; outline:; } 修改光标颜色 input{ outl ...
- splay(1区间翻转区间最值与区间修改)
bzoj1251权限题 题目点这里,你懂得 直接上板子,这个要好好体会 操作是最经典的. #include <algorithm> #include <iostream> #i ...
- 前端——语言——Core JS——《The good part》读书笔记——第七章节(正则)
本章介绍正则表达式的内容.正则表达式是一门独立的语言,它拥有自己的语法规则,在学习本章之前需要了解基本的语法规则. 正则表达式是通用的,意味着同样的语法规则可以适用于不同的编程语言,相同的正则表达式在 ...