1

メソッドは知ってtoCharArray()いますが、正規表現に興味があります。2 つの正規表現の速度について質問があります。

    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 つの正規表現が同じ仕事をしています。最初の正規表現が 2 番目の正規表現よりも速いのはなぜですか? . 回答ありがとうございます。

4

1 に答える 1

3

100%断言することはできませんが、理由は 1 つ考えられます。

(?!^)常に 1 回の試行 (1 回の試行) で失敗または成功します。つまり、単一のテストである文字列の開始が見つからない場合です。

(これ(?<=\\G.{1}) は just とまったく同等です(?<=\\G.))に関しては、常に 2 つのステップまたは 2 つのマッチング試行が必要でした。

\\G文字列の先頭または前の一致の最後に一致し、成功した場合でも、正規表現エンジンは単一の文字との一致を試行する必要があり.ます。

たとえば、 string123456の先頭で、次のように指定します。

  • (?!^): すぐに失敗します。
  • (?<=\\G.):\\G成功し.ますが、後ろの文字を探しますが、これは文字列の先頭であるため見つかりません。これで失敗しますが、ご覧のとおり、前の式では 1 ステップに対して 2 ステップを試行しました。

入力文字列の他のすべての位置についても同じことが言えます。に対して常に 2 つのテストを行うのに対し、(?<=\\G.)に対しては 1 つのテストを行い(?!^)ます。

于 2013-09-21T14:37:05.627 に答える