2017-01-03 9 views
1

おそらくまだ私が見ていないPEBKACですが、(?:[^']+|'')+は二重引用符で囲まれていない文字列(Regex: Match double single quote inside stringに基づいており、Regex 101でテスト済み)と一致する必要があります。Java Regexバグ(一重引用符付き)

1は、Javaのパターンオブジェクト内の上記を使用していますつまり、Pattern noSingleQuote = Pattern.compile("(?:[^']+|'')+");場合は、次のようしかし、その後、動作は次のとおりです。

  • マッチした文字列は、単一引用符が含まれていない場合は、すべてのものは、マッチャーリターンOKです真(すなわち、noSingleQuote.matcher("tester").matches()noSingleQuote.matcher("tes''ter").matches()はOKです)
  • マッチした文字列は、単一引用符が含まれない場合は、その後、JDK Matcherは内部で(すなわち、無限ループでnoSingleQuote.matcher("tes'ter").matches()結果)
01無限ループに当たります

ローカルで8u112でテストし、Regex Planet

無限ループが発生する理由と場所を正確にデバッグしませんでした。

アイデア、洞察?

更新:上記の例では、上記の例を再現しません。"select x, y, z where x = ''t'';""select x, y, z where x = 't'';"を使用すると、上記の内容が再現されます。 これはバグ(?)が単引用符のためだけではないことを意味します。

Update2:無限ループではありませんが、文字列自体のスペース数に比例するようです。私が遭遇したプロダクションコードのために、スペースがたくさんある非常に長いStringがあります。私はそれを無限ループと仮定しました。 Mea culpa。

+0

'' 'charsをエスケープしようとしましたか? –

+0

@ I.G.Pascualなぜですか? – f1sh

+0

.. Javaは '' 'を特殊文字として扱い、エスケープする必要があります –

答えて

1

私はあなたが私がJava regex to match start/end tags causes stack overflowで説明した既知の問題をヒットしたとします。簡単に言えば、Java正規表現エンジンは定量化された変更を非効率的に処理するため、そのようなパターンはunrollには良い考えです。 - 他のゼロ個以上の文字を

  • [^']*:あなたのケースでは、パターンは

    ここ
    String pattern = "[^']*(?:''[^']*)*"; 
    

    として定義されなければならない

    、ロジックはをバックトラックはるかに少ないリニアとinvlovesです'

  • (?:''[^']*)* - 0以上のシーケンス:
    • '' - ダブル単一引用符
    • [^']*から'以外のゼロ個以上の文字。
+0

詳細なソースサポートのお返事ありがとうございます。私が質問の最初の文章に書いたように、それは私が見なかったPEBKACでした:) –

0

あなたの無限ループは他の場所にあると思います。

Pattern p = Pattern.compile("(?:[^']+|'')+"); 

public void test(String test) { 
    System.out.println("\ntest = [" + test + "]"); 
    Matcher m = p.matcher(test); 
    while (m.find()) { 
     System.out.println("Found!"); 
     for (int i = 0; i <= m.groupCount(); i++) { 
      System.out.println("Matched (" + i + ") '" + m.group(i) + "'"); 
     } 
    } 
} 

private void test() { 
    test("select x, y, z where x = ''t'';"); 
    test("select x, y, z where x = 't'';"); 
    test("tes'ter"); 

} 

正常に問題なく動作します。

JDK-1.8.0_111

+3

[Areは私のために有効ですか?]の回答を参照してください。(http://meta.stackexchange.com/questions/118992/are-works-for-me-answers-valid) –

+1

@WiktorStribiżew - *回答のポイントOPが彼らの問題を解決するのに役立つはずです。* - 私はOPがグループやm.find()の呼び出しを適切に反復していないと思われます。これは正しく行うことを示すでしょう。 – OldCurmudgeon

+0

@OldCurmudgeon OPは 'matcher#find()'にも言及していませんでした。それは 'matcher#matches()'に関するものです。 –

関連する問題