210 votes

Le moyen le plus rapide de vérifier si la chaîne ne contient que des chiffres

Je sais comment vérifier cela. regex, int.parse , tryparse , en boucle.

Quelqu'un peut-il me dire quel est le moyen le plus rapide de vérifier?

le besoin est seulement de VÉRIFIER pas besoin d'analyser réellement.

302voto

Janiels Points 1955
 bool IsDigitsOnly(string str)

{
  foreach (char c in str)
  {
    if (c < '0' || c > '9')
      return false;
  }

  return true;
}
 

Sera probablement le moyen le plus rapide de le faire.

75voto

TheCodeKing Points 11632

Voici quelques points de repère basés sur 1000000 analyses de la même chaîne:

Mis à jour pour les statistiques release :

 IsDigitsOnly: 384588
TryParse:     639583
Regex:        1329571
 

Voici le code, on dirait que IsDigitsOnly est plus rapide:

 class Program
{
    private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);

    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();
        string test = int.MaxValue.ToString();
        int value;

        watch.Start();
        for(int i=0; i< 1000000; i++)
        {
            int.TryParse(test, out value);
        }
        watch.Stop();
        Console.WriteLine("TryParse: "+watch.ElapsedTicks);

        watch.Reset();
        watch.Start();
        for (int i = 0; i < 1000000; i++)
        {
            IsDigitsOnly(test);
        }
        watch.Stop();
        Console.WriteLine("IsDigitsOnly: " + watch.ElapsedTicks);

        watch.Reset();
        watch.Start();
        for (int i = 0; i < 1000000; i++)
        {
            regex.IsMatch(test);
        }
        watch.Stop();
        Console.WriteLine("Regex: " + watch.ElapsedTicks);

        Console.ReadLine();
    }

    static bool IsDigitsOnly(string str)
    {
        foreach (char c in str)
        {
            if (c < '0' || c > '9')
                return false;
        }

        return true;
    }
}
 

Bien sûr, il est intéressant de noter que TryParse autorise les espaces de début / fin ainsi que les symboles propres à une culture. C'est également limité sur la longueur de la chaîne.

34voto

Florian Gerhardt Points 2966

Le char a déjà un IsDigit (char c) qui fait ceci:

  public static bool IsDigit(char c)
    {
      if (!char.IsLatin1(c))
        return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
      if ((int) c >= 48)
        return (int) c <= 57;
      else
        return false;
    }
 

Vous pouvez simplement faire ceci:

 var string = "839278";
bool digitsOnly = string.All(char.IsDigit);
 

16voto

Branko Dimitrijevic Points 28493

Si vous êtes préoccupé par la performance, ne pas utiliser int.TryParse ni Regex - écrire votre propre (simple) fonction (DigitsOnly ou DigitsOnly2 - dessous, mais n' DigitsOnly3 - LINQ semble subir une surcharge importante).

Aussi, soyez conscient que int.TryParse échouera si la chaîne est trop longue à "monter" en int.

Cette simple référence...

class Program {

    static bool DigitsOnly(string s) {
        int len = s.Length;
        for (int i = 0; i < len; ++i) {
            char c = s[i];
            if (c < '0' || c > '9')
                return false;
        }
        return true;
    }

    static bool DigitsOnly2(string s) {
        foreach (char c in s) {
            if (c < '0' || c > '9')
                return false;
        }
        return true;
    }

    static bool DigitsOnly3(string s) {
        return s.All(c => c >= '0' && c <= '9');
    }

    static void Main(string[] args) {

        const string s1 = "916734184";
        const string s2 = "916734a84";

        const int iterations = 1000000;
        var sw = new Stopwatch();

        sw.Restart();
        for (int i = 0 ; i < iterations; ++i) {
            bool success = DigitsOnly(s1);
            bool failure = DigitsOnly(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            bool success = DigitsOnly2(s1);
            bool failure = DigitsOnly2(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly2: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            bool success = DigitsOnly3(s1);
            bool failure = DigitsOnly3(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("DigitsOnly3: {0}", sw.Elapsed));

        sw.Restart();
        for (int i = 0; i < iterations; ++i) {
            int dummy;
            bool success = int.TryParse(s1, out dummy);
            bool failure = int.TryParse(s2, out dummy);
        }
        sw.Stop();
        Console.WriteLine(string.Format("int.TryParse: {0}", sw.Elapsed));

        sw.Restart();
        var regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
        for (int i = 0; i < iterations; ++i) {
            bool success = regex.IsMatch(s1);
            bool failure = regex.IsMatch(s2);
        }
        sw.Stop();
        Console.WriteLine(string.Format("Regex.IsMatch: {0}", sw.Elapsed));

    }

}

...produit le résultat suivant...

DigitsOnly: 00:00:00.0346094
DigitsOnly2: 00:00:00.0365220
DigitsOnly3: 00:00:00.2669425
int.TryParse: 00:00:00.3405548
Regex.IsMatch: 00:00:00.7017648

7voto

Petar Ivanov Points 29530

Cela devrait fonctionner:

 Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled)
 

int.Parse ou int.TryParse ne fonctionnera pas toujours, car la chaîne peut contenir plus de chiffres qu'un int peut contenir.

Si vous allez faire cette vérification plus d'une fois, il est utile d'utiliser une expression rationnelle compilée - cela prend plus de temps la première fois, mais est beaucoup plus rapide par la suite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X