8

私は数字を一致させることができることを知っていますPattern.compile("\\d*");

ただし、長い最小値/最大値は処理しません。

例外に関連するパフォーマンスの問題については、本当に長い場合を除いて、longを解析しようとはしません。

if ( LONG_PATTERN.matcher(timestampStr).matches() ) {
    long timeStamp = Long.parseLong(timestampStr);
    return new Date(timeStamp);
} else {
    LOGGER.error("Can't convert " + timestampStr + " to a Date because it is not a timestamp! -> ");
    return null;
}

つまり、try / catchブロックは必要なく、通常のJavalongのサイズから外れた「564654954654464654654567879865132154778」のような長い間例外が発生したくないということです。

誰かがこの種のプリミティブJavaタイプの必要性を処理するパターンを持っていますか?JDKはそれを自動的に処理するための何かを提供しますか?Javaにフェイルセーフな構文解析メカニズムはありますか?

ありがとう


編集:「悪い長い文字列」は例外的なケースではないと想定してください。私はベンチマークを求めているのではなく、長くて何も表していない正規表現を求めています。正規表現チェックに必要な追加の時間を認識していますが、少なくとも私の長い構文解析は常に一定であり、「不良な長い文字列」の割合に依存することはありません。

リンクを再度見つけることはできませんが、StackOverflowに優れた解析ベンチマークがあります。これは、samsでコンパイルされた正規表現の再利用が非常に高速であり、例外をスローするよりもはるかに高速であるため、例外のしきい値が小さいとシステムが遅くなることを明確に示しています。追加の正規表現チェックよりも。

4

3 に答える 3

15

aの最小値long-9,223,372,036,854,775,808、であり、最大値は9,223,372,036,854,775,807です。したがって、最大19桁です。したがって、\d{1,19}おそらくオプションで、文字列の終わりに一致するように、そこに到達する必要が-あります^$

だから大まかに

Pattern LONG_PATTERN = Pattern.compile("^-?\\d{1,19}$");

...またはそれらの線に沿った何か、そしてあなたがコンマを許可しない(またはすでにそれらを削除している)と仮定します。

gexicideがコメントで指摘しているように、上記では、などの無効な値の範囲を(比較して)小さくすることができます9,999,999,999,999,999,999。正規表現をさらに複雑にすることも、上記の方法で無効な数値の大部分を取り除くことを受け入れることで、発生する解析例外の数を減らすことができます。

于 2012-06-28T11:06:35.370 に答える
3

この正規表現は、必要なことを実行する必要があります。

^(-9223372036854775808|0)$|^((-?)((?!0)\d{1,18}|[1-8]\d{18}|9[0-1]\d{17}|92[0-1]\d{16}|922[0-2]\d{15}|9223[0-2]\d{14}|92233[0-6]\d{13}|922337[0-1]\d{12}|92233720[0-2]\d{10}|922337203[0-5]\d{9}|9223372036[0-7]\d{8}|92233720368[0-4]\d{7}|922337203685[0-3]\d{6}|9223372036854[0-6]\d{5}|92233720368547[0-6]\d{4}|922337203685477[0-4]\d{3}|9223372036854775[0-7]\d{2}|922337203685477580[0-7]))$

ただし、この正規表現は、、などの追加のシンボルを検証しません。+また、考えられるすべてのLong値を検証する必要がある場合は、この正規表現をアップグレードする必要があります。L_

于 2016-12-13T10:06:33.117 に答える
1

このケースが非常に頻繁に発生しない限り、NumberFormatExceptionをキャッチするだけです。

別の方法は、長いリテラルのみを許可するパターンを使用することです。このようなパターンは非常に複雑な場合があります。

3番目の方法は、最初に数値をBigIntとして解析することです。次に、それをLong.MAX_VALUEおよびLong.MIN_VALUEと比較して、longの範囲内にあるかどうかを確認できます。ただし、これにもコストがかかる可能性があります。

また、注意:longの解析は非常に高速で、非常に最適化された方法です(たとえば、1つのステップで2桁の解析を試みます)。パターンマッチングの適用は、解析を実行するよりもさらにコストがかかる可能性があります。解析が遅いのは、NumberFormatExceptionをスローすることだけです。したがって、例外があまり頻繁に発生しない場合は、単に例外をキャッチすることが最善の方法です。

于 2012-06-28T11:05:26.760 に答える