[性能优化]-04java编程-避免正则表达式引发的回溯问题


正则表达式
一、是什么?
	就是一个概念,不同语言有不同的实现。
	就是一个公式,使用一些特定的“元字符”来检索、匹配、替换符合规则的字符串。
		元字符,如普通字符、标准字符、限定字符、定位字符等

二、正则表达式 引擎
	工作流程:程序对“公式”进行语法分析,并建立语法分析树。根据语法分析树 结合 正则表达式的引擎生成 执行程序(这个执行程序,叫做状态机/自动机),用于字符串匹配。
	正则表达式引擎,就是一套核心算法,用于建立状态机。
	
	状态机的分类(编程语言中的正则表达式库,都是基于NFA实现的。)
		DFA自动机(Deterministic Final Automata 确定有限状态自动机)
			缺点:构造代价高
			优点:效率快。若字符串长度是n,则匹配时间复杂度O(n)
		NFA自动机(Non Deterministic Final Automata 非确定有限状态自动机)
			优点:构造代价低
				支持高级功能(如捕获group、环视、占有优先量),高级功能都是基于子表达式独立进行匹配。
			缺点:效率慢(匹配过程存在 分支、回溯)。若字符串长度是n,且状态数为s,则匹配时间复杂度O(ns)。
			原理
				匹配流程?
				存在问题?回溯。源于,贪婪特性
				避免 回溯?公式中使用+、?、*、{min,max}等时,不同模式的处理方式不同
					1、贪婪模式 Greedy。最大限度匹配更多内容,且回溯
						text=“abbc” 
						regex=“ab{1,3}c”   //匹配3个b
					2、懒惰模式 Reluctant。尽可能少的匹配,避免回溯。通过?开启。
						text=“abc” 
						regex=“ab{1,3}?c”   //匹配1个b
					3、独占模式 Posssessive。最大限度匹配更多的内容,但不回溯。通过+开启。
						text=“abbc” 
						regex=“ab{1,3}+bc”
				避免回溯?开启懒惰模式、或独占模式

三、正则表达式的优化
1、少用贪婪模式,多用独占模式
	避免回溯
2、减少分支选择
	1)考虑顺序。常用选项放前面,快速匹配
	2)提取公共部分。(abcd|abef)替换为ab(cd|ef)。优先匹配ab,若无则放弃。
	3)简单分支用index。三次index效率可能优于(X|Y|Z)
3、减少捕获嵌套
	捕获组,正则表达式中,子表达式参与匹配,并将匹配的结果放入数字编号/显示命名的数组中,方便后面使用。一个()就是一个捕获组,支持嵌套。
		例子//编号0,代表匹配的整个内容
        String reg = "(<input.*?>)(.*?)(</input>)";
	非捕获组,参与匹配,不获取某分组的内容。表达式一般为 (?:exp)
		例子//用(?:X) 代替 (X)
        String reg = "(?:<input.*?>)(.*?)(?:</input>)";


应用场景:如,注册页面中手机号校验、邮箱校验

总结,尽可能不用正则表达式,除非你已经做好性能排查。

任何一个细节问题,都有可能导致性能问题,根本原因是我们对这项技术的了解不够透彻。掌握方法论,学会透过现象看本质。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值