问个正则死循环的问题 .*?开头的正则为什么容易造成死循环? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 .*?<value><源代码比较长,当源代码中匹配不到<value><就造成了死循环。个人认为.*?<value><和<value><效果应该是一样的哈,但是为什么前者会 不是死循环,只是循环的次数太多,占用的时间过长罢了在匹配成功的情况下,一般不会出现这种情况,在匹配失败的情况下,源字符串的长度越长,循环的次数就越多,当源字符串达到一定长度的时候,会出现假死现象这个跟NFA引擎的匹配原理相关,要完全说清楚,不是一句话两句话的事,简单的说一下吧源字符串以“abcde”为例,说明一下.*?<value> 小数点匹配除\n外的任意字符,而*?是忽略优先的(或者叫非贪婪模式),.*?可以看作是一组,后面接字符“<”,再后面接字符“v”匹配过程:首先从字符串开始的位置匹配,“.*?”取得控制权,但是由于它是忽略优先的,所以什么都不匹配,把控制权关给“<”,如果匹成功,控制权关给“v”,如果匹配不成功,那么就会发生回溯,控制权交给“.*?”,这里由于第一个字符是“a”,所以“<”匹配不成功,这时由“.*?”来匹配“a”,然后继续尝试向后匹配“.*?”取得控制权,但是由于它是忽略优先的,所以什么都不匹配,把控制权关给“<”,由于第二个字符是“b”,所以“<”匹配不成功,控制权重新关给“.*?”,匹配成功,这时由“.*?”来匹配“a”,然后继续尝试向后匹配重复以上过程,一直到由“.*?”匹配了“abcde”,这时控制权交给“<”,到了字符串结束位置,匹配不成功,这时候会报整个表达式匹配不成功正则引擎向前传动,由“ab”之间的位置开始尝试匹配,再重复以上过程,直到匹配失败正则引擎继续传动,一直到字符串的结束位置,这时会报告整个匹配过程失败,匹配完成所以源字符串越长,匹配过程中控制权的交替就越多,而这种操作是很耗时的,甚至可以相当于无限循环那么如何解决这个问题如果是从字符串开始位置匹配的,那么在前面加上“^”,即“^.*?<value>”,一般稍微做了一点优化的正则引擎,只要第一次从开始位置匹配失败了,就不会再尝试第二个位置开始的匹配,直接报告整个匹配过程失败,那么匹配性能的提高就是指数级的但这还不够,如果源字符串很长,那么这个匹配时间仍然会很长,所以通常情况下,需要采用匹配优先(或者叫贪婪模式)的方式,可以用排除型字符组或者否定正向环视来实现,因为这里要排除的是一个子字符串,所以用否定型正向环视^((?!<value>).)*<value>这样的优化会将匹配效率再提升一个数量级当然,这并不是最终的优化形态,还可以采用固化分组进行优化^(?>(?:(?!<value>).)*)<value>涉及到长字符串匹配或对性能要求较高时,不要使用.*?这种忽略优先(非贪婪模式)的写法 select @@identity问题 调试c#时出现了错误,在网上找了好多原因,还是没有解决,特来CSDN向大神们请教。 求解释?? winform中combobox值相互影响的问题 哪位高人指点一下SMTP和POP3服务组件的开发思路呀,TKS 关于DataGrid方法重载; Response.Write无法输出结果到页面 请教C# winform中datagrid合计行的问题 如何把一个sqlserver中的日期字段绑定到dateTimePicker中 wpf 制作网页如何使用Session 正则表达式提取内容问题
个人认为.*?<value><和<value><效果应该是一样的哈,但是为什么前者会
不是死循环,只是循环的次数太多,占用的时间过长罢了
在匹配成功的情况下,一般不会出现这种情况,在匹配失败的情况下,源字符串的长度越长,循环的次数就越多,当源字符串达到一定长度的时候,会出现假死现象这个跟NFA引擎的匹配原理相关,要完全说清楚,不是一句话两句话的事,简单的说一下吧源字符串以“abcde”为例,说明一下
.*?<value> 小数点匹配除\n外的任意字符,而*?是忽略优先的(或者叫非贪婪模式),.*?可以看作是一组,后面接字符“<”,再后面接字符“v”匹配过程:
首先从字符串开始的位置匹配,“.*?”取得控制权,但是由于它是忽略优先的,所以什么都不匹配,把控制权关给“<”,如果匹成功,控制权关给“v”,如果匹配不成功,那么就会发生回溯,控制权交给“.*?”,这里由于第一个字符是“a”,所以“<”匹配不成功,这时由“.*?”来匹配“a”,然后继续尝试向后匹配
“.*?”取得控制权,但是由于它是忽略优先的,所以什么都不匹配,把控制权关给“<”,由于第二个字符是“b”,所以“<”匹配不成功,控制权重新关给“.*?”,匹配成功,这时由“.*?”来匹配“a”,然后继续尝试向后匹配
重复以上过程,一直到由“.*?”匹配了“abcde”,这时控制权交给“<”,到了字符串结束位置,匹配不成功,这时候会报整个表达式匹配不成功正则引擎向前传动,由“ab”之间的位置开始尝试匹配,再重复以上过程,直到匹配失败正则引擎继续传动,一直到字符串的结束位置,这时会报告整个匹配过程失败,匹配完成所以源字符串越长,匹配过程中控制权的交替就越多,而这种操作是很耗时的,甚至可以相当于无限循环那么如何解决这个问题
如果是从字符串开始位置匹配的,那么在前面加上“^”,即“^.*?<value>”,一般稍微做了一点优化的正则引擎,只要第一次从开始位置匹配失败了,就不会再尝试第二个位置开始的匹配,直接报告整个匹配过程失败,那么匹配性能的提高就是指数级的但这还不够,如果源字符串很长,那么这个匹配时间仍然会很长,所以通常情况下,需要采用匹配优先(或者叫贪婪模式)的方式,可以用排除型字符组或者否定正向环视来实现,因为这里要排除的是一个子字符串,所以用否定型正向环视^((?!<value>).)*<value>
这样的优化会将匹配效率再提升一个数量级当然,这并不是最终的优化形态,还可以采用固化分组进行优化
^(?>(?:(?!<value>).)*)<value>涉及到长字符串匹配或对性能要求较高时,不要使用.*?这种忽略优先(非贪婪模式)的写法