2013-09-21 75 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'因此它必須檢查它,但我認爲差異非常小。 –

相關問題