2013-09-21 61 views
1

我知道toCharArray()方法,但我对正则表达式感兴趣。我有问题要问你大约两个正则表达式的速度:查找字符串中的所有字母与正则表达式

String s = "123456"; 
    // Warm up JVM 
    for (int i = 0; i < 10000000; ++i) { 
     String[] arr = s.split("(?!^)"); 
     String[] arr2 = s.split("(?<=\\G.{1})"); 
    } 
    long start = System.nanoTime(); 
    String[] arr = s.split("(?!^)"); 
    long stop = System.nanoTime(); 
    System.out.println(stop - start); 
    System.out.println(Arrays.toString(arr)); 
    start = System.nanoTime(); 
    String[] arr2 = s.split("(?<=\\G.{1})"); 
    stop = System.nanoTime(); 
    System.out.println(stop - start); 
    System.out.println(Arrays.toString(arr2)); 

输出:

Run 1: 
3158 
[1, 2, 3, 4, 5, 6] 
3947 
[1, 2, 3, 4, 5, 6] 

Run 2: 
2763 
[1, 2, 3, 4, 5, 6] 
3158 
[1, 2, 3, 4, 5, 6] 

2的正则表达式都在做同样的工作。为什么第一个正则表达式比第二个正则表达式更快? 。感谢您的回答。

+1

看看[我如何写一个正确的micro-benchmark-in-java](http://stackoverflow.com/questions/504103/how-do-i-write-a -correct-micro-benchmark-in-java) – Pshemo

+0

感谢你的关注。你是正则表达式的爱好者:)你知道哪个正则表达式更快,并解释为什么? –

+0

如果您有答案,请分享@Sniffer –

回答

3

我绝对不能100%确定,但我可以想到一个原因。

(?!^)总是失败或一次成功(一次尝试),也就是说,如果它找不到只是单个测试的字符串开始。

至于(?<=\\G.{1})(它恰好等于(?<=\\G.)它总是涉及两个步骤或两个匹配尝试。

\\G可以匹配字符串的开头或匹配的结尾,即使成功,正则表达式引擎仍然需要尝试匹配单个字符.

例如,在你的字符串123456,在字符串的开头:

  • (?!^):立即失败。
  • (?<=\\G.)\\G成功,但随后查找.,但无法找到背后,因为这是启动的串所以现在它没有一个字,但你可以看到它试图分两步对一步到位的以前的表达。

输入字符串中的每个其他位置也是如此。始终对(?<=\\G.)进行两次测试,对(?!^)进行单次测试。

+0

感谢您的回答,如果我不把\\ G选择哪一个s.split(“(?<=。”)或s.split(“(?!^)”); –

+1

@MelihAltıntaş下面的答案也是一个猜测,你需要运行一个基准来确定,但我认为'(?<= ^)'比'(?<=。)'快,因为后者匹配除换行符以外的所有内容'\ n'因此它必须检查它,但我认为差异非常小。 –

相关问题