10

ASP.netプロジェクトでは、ユーザー入力のいくつかの基本的なデータ型を検証する必要があります。データ型は、数値、小数、日時などです。

パフォーマンスの観点から私が取るべき最善のアプローチは何ですか?それをするのか、Regex.IsMatch()それともするのTryParse()か?

前もって感謝します。

4

4 に答える 4

10

TryParseRegex.IsMatch2つの根本的に異なることに使用されます。Regex.IsMatch問題の文字列が特定のパターンに一致するかどうかを示します。はい/いいえの答えを返します。TryParse可能であれば実際に値を変換し、成功したかどうかを通知します。

正規表現の作成に細心の注意を払っていない限り、いつ戻るかを返すRegex.IsMatchことができます。たとえば、を解析する単純なケースを考えてみましょう。あなたと一緒に:trueTryParsefalsebyteTryParse

byte b;
bool isGood = byte.TryParse(myString, out b);

の値がmyString0〜255の場合、TryParseはを返しtrueます。

それでは、で試してみましょうRegex.IsMatch。見てみましょう、その正規表現はどうあるべきですか?@"\d+"ただ言うことも、言うこともできません@\d{1,3}"。フォーマットの指定は非常に難しい作業になります。先頭の0、先頭と末尾の空白を処理する必要がありますが、許可する必要はあり255ません256

そして、それは3桁の数字を解析するためだけのものです。intまたはを解析する場合、ルールはさらに複雑になりますlong

正規表現は、フォームを決定するのに最適です。価値を決定することになると、彼らはひどいです。標準のデータ型にはすべて制限があるため、その値を決定することは、数値が有効かどうかを判断することの一部です。

TryParse検証を行う信頼性の高い正規表現を考え出すという頭痛の種を減らすためだけに、可能な限り使用することをお勧めします。TryParseネイティブタイプの特定のものは、同等の正規表現よりも高速に実行される可能性があります(ほぼ確実だと思います) 。

上記のように、私はおそらくあなたのWebページがその生涯を通してあなたTryParseまたは--totalを実行するのに費やすよりもこの答えに多くの時間を費やしました。Regex.IsMatchこれらのことを実行する時間は、Webサイトが実行している他のすべての状況では非常に短いため、問題について熟考するために費やす時間は無駄になります。

TryParse簡単なので、できれば使用してください。それ以外の場合はを使用しますRegex

于 2011-04-19T13:08:37.470 に答える
6

他の人が言うように、それに答える最良の方法はそれを測定することです;)

    static void Main(string[] args)
    {

        List<double> meansFailedTryParse = new List<double>();
        List<double> meansFailedRegEx = new List<double>();
        List<double> meansSuccessTryParse = new List<double>();
        List<double> meansSuccessRegEx = new List<double>();


        for (int i = 0; i < 1000; i++)
        {


            string input = "123abc";

            int res;
            bool res2;
            var sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansFailedTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);

            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansFailedRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);

            input = "123";
            sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansSuccessTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);


            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansSuccessRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);
        }

        Console.WriteLine("Failed TryParse mean execution time     " + meansFailedTryParse.Average());
        Console.WriteLine("Failed Regex mean execution time        " + meansFailedRegEx.Average());

        Console.WriteLine("successful TryParse mean execution time " + meansSuccessTryParse.Average());
        Console.WriteLine("successful Regex mean execution time    " + meansSuccessRegEx.Average());
    }
}
于 2011-04-19T11:10:29.847 に答える
4

正規表現にすべてを実行させようとしないでください。

単純な正規表現で90%の道のりが得られ、必要なすべてのことを実行できるようになると、複雑さが10倍以上になることがあります。

次に、最も簡単な解決策は、正規表現を使用してフォームをチェックし、値のチェックに古き良きコードを使用することです。

日付を例にとると、正規表現を使用して日付形式との一致を確認してから、キャプチャグループを使用して個々の値の値を確認します。

于 2012-12-04T18:33:40.077 に答える
1

TryParseの方が速いと思いますが、さらに重要なのは、表現力が高いことです。

使用している各データ型のすべての有効な値を考慮すると、正規表現はかなり見苦しくなります。たとえば、DateTimeでは、月が1〜12であり、その日がその特定の月の有効な範囲内にあることを確認する必要があります。

于 2011-04-19T11:40:17.433 に答える