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]

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

4

1 回答 1

3

我永远不能百分百确定,但我能想到一个原因。

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

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

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

例如,在您的 string123456中,在字符串的开头:

  • (?!^): 立即失败。
  • (?<=\\G.):\\G成功,但是它会查找.但找不到后面的字符,因为这是字符串的开头,所以现在它失败了,但是正如您所看到的,它尝试了两步,而不是前一个表达式的一步。

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

于 2013-09-21T14:37:05.627 回答