回溯

-- Start

在上一节中我们了解了什么是回溯,通常量词和多选结构会引起回溯。假设用表达式 ^.*([0-9]+) 去匹配 "恋曲 1990",括号中会匹配什么呢?我们的本意是匹配 1990, 但是遗憾的是它只能匹配一个 0, 为什么会这样呢?因为星号是贪婪量词,.* 会一直匹配到字符串的结尾,为了使整个表达式能够匹配成功,引擎会进行回溯,吐出一个字符,之后再次尝试匹配整个表达式,此时匹配成功,所以 ([0-9]+) 只能匹配一个 0。为了使 ([0-9]+) 能够匹配 1990, 我们可以使用非贪婪量词,将表达式修改为 ^.*?([0-9]+) 即可。

我们在看一个例子,假设我想匹配一段包含数字,小写字母空格的字符串(如:i love regular express 1314),我们用表达式 ([0-9]|[a-z]| )* ,这个表达式在功能上完全没有问题,但是它需要进行大量的回溯,原因是我们把 [0-9] 放在了第一个分支,如果第一分支匹配不成功,引擎就需要回溯,我们应该把能够匹配最多字符的分支放在第一位,很显然,本例应该把 [a-z] 放在第一位,这样就减少了引擎回溯的次数,当然对于本例来说,我们没必要使用多选分支,而应该使用字符组 [0-9a-z ]。

通过这两个例子大家可以看到,在正则表达式中,回溯的概念非常重要,回溯不仅会影响表达式的匹配结果,大量的回溯将严重影响表达式的性能,所以在使用量词和多选分支的时候,我们应该在保证准确性的前提下,想方设法减少回溯发生的次数。

--更多参见:正则表达式精萃
-- 声 明:转载请注明出处
-- Last Updated on 2012-05-26
-- Written by ShangBo on 2012-05-24
-- End


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值