您的位置:首页 > 编程语言 > Java开发

Java regex正则表达式类似死循环问题

2012-07-24 22:41 281 查看
Java regex正则表达式类似死循环问题,详见:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988218

这个问题其实是由于正则表达式很复杂时,java regex复杂度过高(复杂度成指数级),导致类似死循环的问题。

测试代码:

//

public static void main(String[] args) {
long begin = System.currentTimeMillis();
System.out.println("begin!");
//Pattern pattern = Pattern.compile("^([+-]?((0[xX](\\p{XDigit}+))|(((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)))|[n|N]?'([^']*(?:'')*[^']*)*')");
//可以简化成下面这样的,注意  \p、XDigit、Digit之类的是java regex才有的语法
Pattern pattern = Pattern.compile("^('([^']*(?:'')*[^']*)*')");
Matcher matcher = pattern.matcher("'%)) order by ANGEBOT.ID");
System.out.println(matcher.find());

long end = System.currentTimeMillis();
System.out.println((end-begin)/1000+"s used!");
System.out.println("finished!");
}


//

考虑解决方案:

1. native调用c++方法

2. 调用python或perl代码(exec调用方式,linux开一个进程去执行,这样效率可想而知。。。)

3.考虑优化正则表达式(事后证明是最有效的解决方案,哈哈)

测试用例:

尝试了几种方法,下面的我测试的一些结论,用下面的2组字符串来测试:

第1组:

text="'%)) order by ANGEBOT.ID";  

regex ="^('([^']*(?:'')*[^']*)*')";  

第2组:

text = "%)) ERROR: JDWP Unable to 2";

regex = "([^']*)*'";

测试结果:

java:2个例子都会跑死。。。超过3天,执行时间跟text字符串的长度基本上成指数级增长
python:2个例子都会跑死。。。超过3天,而且python更慢
c++11:用Microsoft Visual Studio 2010, 2个例子瞬间跑完(<10ms),可惜最新的g++4.7都还没有完全实现regex模块功能...
c++ boost:2个例子,regex库跑会内存栈溢出。。。
perl:2个例子瞬间跑完(<10ms)
c pcre/c++ pcre++:2个例子瞬间跑完(<10ms)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息