web-dev-qa-db-fra.com

Identifier si une chaîne est un nombre

Si j'ai ces chaînes:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

Existe-t-il une commande, telle que IsNumeric() ou quelque chose d'autre, permettant d'identifier si une chaîne est un nombre valide?

670
Gold
int n;
bool isNumeric = int.TryParse("123", out n);

Mise à jour à partir de C # 7:

var isNumeric = int.TryParse("123", out int n);

Les var s peuvent être remplacés par leurs types respectifs!

1051
mqp

Cela retournera vrai si input est tous les nombres. Je ne sais pas si c'est mieux que TryParse, mais cela fonctionnera.

Regex.IsMatch(input, @"^\d+$")

Si vous voulez simplement savoir s’il comporte un ou plusieurs chiffres mélangés à des caractères, laissez de côté le ^+ et le $.

Regex.IsMatch(input, @"\d")

Edit: En fait, je pense que c'est mieux que TryParse car une très longue chaîne pourrait potentiellement déborder de TryParse.

344
John M Gant

Vous pouvez aussi utiliser:

stringTest.All(char.IsDigit);

Il retournera true pour tous les chiffres (et non float) et false si la chaîne d'entrée est quelconque, de manière alphanumérique.

notez svp: stringTest ne devrait pas être une chaîne vide car cela passerait le test d'être numérique.

173
Kunal Goel

J'ai utilisé cette fonction plusieurs fois:

public static bool IsNumeric(object Expression)
{
    double retNum;

    bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
    return isNum;
}

Mais vous pouvez aussi utiliser;

bool b1 = Microsoft.VisualBasic.Information.IsNumeric("1"); //true
bool b2 = Microsoft.VisualBasic.Information.IsNumeric("1aa"); // false

De Analyse comparative des options IsNumeric

alt text
(source: aspalliance.com )

alt text
(source: aspalliance.com )

124
Nelson Miranda

C'est probablement la meilleure option en C #.

Si vous voulez savoir si la chaîne contient un nombre entier (entier):

string someString;
// ...
int myInt;
bool isNumerical = int.TryParse(someString, out myInt);

La méthode TryParse essaiera de convertir la chaîne en un nombre (entier) et si elle réussit, elle retournera la valeur true et placera le nombre correspondant dans myInt. Si ça ne peut pas, ça retourne faux.

Les solutions utilisant la variante int.Parse(someString) indiquée dans d'autres réponses fonctionnent, mais elles sont beaucoup plus lentes car lancer des exceptions coûte très cher. TryParse(...) a été ajouté au langage C # dans la version 2 et, jusque-là, vous n'aviez pas le choix. Vous devez maintenant éviter l’alternative Parse().

Si vous souhaitez accepter les nombres décimaux, la classe décimale a également une méthode .TryParse(...). Remplacez int par décimal dans la discussion ci-dessus et les mêmes principes s'appliquent.

32
Euro Micelli

Vous pouvez toujours utiliser les méthodes TryParse intégrées à de nombreux types de données pour voir si la chaîne en question passera.

Exemple.

decimal myDec;
var Result = decimal.TryParse("123", out myDec);

Le résultat serait alors = True

decimal myDec;
var Result = decimal.TryParse("abc", out myDec);

Le résultat serait alors = False

25
TheTXI

Au cas où vous ne voudriez pas utiliser int.Parse ou double.Parse, vous pouvez vous lancer vous-même avec quelque chose comme ceci:

public static class Extensions
{
    public static bool IsNumeric(this string s)
    {
        foreach (char c in s)
        {
            if (!char.IsDigit(c) && c != '.')
            {
                return false;
            }
        }

        return true;
    }
}
19
BFree

Je sais que c'est un vieux fil, mais aucune des réponses ne l'a vraiment fait pour moi - soit inefficace, soit non encapsulée pour une réutilisation facile. Je voulais également m'assurer qu'il renvoyait false si la chaîne était vide ou nulle. TryParse renvoie true dans ce cas (une chaîne vide ne provoque pas d'erreur lors de l'analyse syntaxique). Alors, voici ma méthode d'extension de chaîne:

public static class Extensions
{
    /// <summary>
    /// Returns true if string is numeric and not empty or null or whitespace.
    /// Determines if string is numeric by parsing as Double
    /// </summary>
    /// <param name="str"></param>
    /// <param name="style">Optional style - defaults to NumberStyles.Number (leading and trailing whitespace, leading and trailing sign, decimal point and thousands separator) </param>
    /// <param name="culture">Optional CultureInfo - defaults to InvariantCulture</param>
    /// <returns></returns>
    public static bool IsNumeric(this string str, NumberStyles style = NumberStyles.Number,
        CultureInfo culture = null)
    {
        double num;
        if (culture == null) culture = CultureInfo.InvariantCulture;
        return Double.TryParse(str, style, culture, out num) && !String.IsNullOrWhiteSpace(str);
    }
}

Simple à utiliser:

var mystring = "1234.56789";
var test = mystring.IsNumeric();

Ou, si vous souhaitez tester d'autres types de nombres, vous pouvez spécifier le "style". Ainsi, pour convertir un nombre avec un exposant, vous pouvez utiliser:

var mystring = "5.2453232E6";
var test = mystring.IsNumeric(style: NumberStyles.AllowExponent);

Ou pour tester une chaîne potentielle Hex, vous pouvez utiliser:

var mystring = "0xF67AB2";
var test = mystring.IsNumeric(style: NumberStyles.HexNumber)

Le paramètre optionnel 'culture' peut être utilisé de la même manière.

Il est limité par l'impossibilité de convertir des chaînes trop volumineuses pour être contenues dans un double, mais il s'agit d'une exigence limitée et si vous travaillez avec des nombres plus grands, vous aurez probablement besoin d'une gestion supplémentaire des numéros spécialisés. fonctionne de toute façon.

14
cyberspy

Si vous voulez capturer un plus grand nombre de nombres, à la PHP is_numeric , vous pouvez utiliser ce qui suit:

// From PHP documentation for is_numeric
// (http://php.net/manual/en/function.is-numeric.php)

// Finds whether the given variable is numeric.

// Numeric strings consist of optional sign, any number of digits, optional decimal part and optional
// exponential part. Thus +0123.45e6 is a valid numeric value.

// Hexadecimal (e.g. 0xf4c3b00c), Binary (e.g. 0b10100111001), Octal (e.g. 0777) notation is allowed too but
// only without sign, decimal and exponential part.
static readonly Regex _isNumericRegex =
    new Regex(  "^(" +
                /*Hex*/ @"0x[0-9a-f]+"  + "|" +
                /*Bin*/ @"0b[01]+"      + "|" + 
                /*Oct*/ @"0[0-7]*"      + "|" +
                /*Dec*/ @"((?!0)|[-+]|(?=0+\.))(\d*\.)?\d+(e\d+)?" + 
                ")$" );
static bool IsNumeric( string value )
{
    return _isNumericRegex.IsMatch( value );
}

Test de l'unité:

static void IsNumericTest()
{
    string[] l_unitTests = new string[] { 
        "123",      /* TRUE */
        "abc",      /* FALSE */
        "12.3",     /* TRUE */
        "+12.3",    /* TRUE */
        "-12.3",    /* TRUE */
        "1.23e2",   /* TRUE */
        "-1e23",    /* TRUE */
        "1.2ef",    /* FALSE */
        "0x0",      /* TRUE */
        "0xfff",    /* TRUE */
        "0xf1f",    /* TRUE */
        "0xf1g",    /* FALSE */
        "0123",     /* TRUE */
        "0999",     /* FALSE (not octal) */
        "+0999",    /* TRUE (forced decimal) */
        "0b0101",   /* TRUE */
        "0b0102"    /* FALSE */
    };

    foreach ( string l_unitTest in l_unitTests )
        Console.WriteLine( l_unitTest + " => " + IsNumeric( l_unitTest ).ToString() );

    Console.ReadKey( true );
}

Gardez à l'esprit que ce n'est pas parce qu'une valeur est numérique qu'elle peut être convertie en un type numérique. Par exemple, "999999999999999999999999999999.9999999999" est une valeur numérique parfaitement valide, mais elle ne rentre pas dans un type numérique .NET (il ne s'agit pas d'un type défini dans la bibliothèque standard).

12
JDB

Si vous voulez vérifier si une chaîne est un nombre (je suppose que c'est une chaîne, car si c'est un nombre, vous savez que c'est un).

  • Sans regex et
  • en utilisant le code de Microsoft autant que possible

vous pouvez aussi faire:

public static bool IsNumber(this string aNumber)
{
     BigInteger temp_big_int;
     var is_number = BigInteger.TryParse(aNumber, out temp_big_int);
     return is_number;
}

Cela va prendre en charge les méchants habituels:

  • Moins (-) ou plus (+) au début
  • contient un caractère décimal BigIntegers n'analysera pas les nombres avec des points décimaux. (Donc: BigInteger.Parse("3.3") lèvera une exception et TryParse pour la même chose retournera false)
  • pas de chiffres amusants
  • couvre les cas où le nombre est plus grand que l'utilisation habituelle de Double.TryParse

Vous devrez ajouter une référence à System.Numerics et avoir using System.Numerics; au-dessus de votre classe (enfin, le second est un bonus, je suppose :)

9
Noctis

Vous pouvez utiliser TryParse pour déterminer si la chaîne peut être analysée en un entier.

int i;
bool bNum = int.TryParse(str, out i);

Le booléen vous dira si cela a fonctionné ou non.

9
Craig

Je suppose que cette réponse sera simplement perdue entre toutes les autres, mais enfin, voilà.

Je me suis retrouvé sur cette question via Google parce que je voulais vérifier si une string était numeric afin que je puisse simplement utiliser double.Parse("123") au lieu de la méthode TryParse().

Pourquoi? Car il est embêtant de devoir déclarer une variable out et de vérifier le résultat de TryParse() avant de savoir si l’analyse a échoué ou non. Je veux utiliser le ternary operator pour vérifier si le string est numerical, puis l’analyser dans la première expression ternaire ou fournir une valeur par défaut dans la deuxième expression ternaire.

Comme ça:

var doubleValue = IsNumeric(numberAsString) ? double.Parse(numberAsString) : 0;

C'est juste beaucoup plus propre que:

var doubleValue = 0;
if (double.TryParse(numberAsString, out doubleValue)) {
    //whatever you want to do with doubleValue
}

J'ai fait un couple extension methods pour ces cas:


Méthode d'extension un

public static bool IsParseableAs<TInput>(this string value) {
    var type = typeof(TInput);

    var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
        new[] { typeof(string), type.MakeByRefType() }, null);
    if (tryParseMethod == null) return false;

    var arguments = new[] { value, Activator.CreateInstance(type) };
    return (bool) tryParseMethod.Invoke(null, arguments);
}

Exemple:

"123".IsParseableAs<double>() ? double.Parse(sNumber) : 0;

Parce que IsParseableAs() essaie d'analyser la chaîne selon le type approprié au lieu de simplement vérifier si la chaîne est "numérique", cela devrait être assez sûr. Et vous pouvez même l'utiliser pour les types non numériques ayant une méthode TryParse(), comme DateTime.

La méthode utilise la réflexion et vous appelez la méthode TryParse() à deux reprises, ce qui n'est bien sûr pas aussi efficace, mais tout ne doit pas être optimisé. Parfois, la commodité est plus importante.

Cette méthode peut également être utilisée pour analyser facilement une liste de chaînes numériques dans une liste de double ou un autre type avec une valeur par défaut sans avoir à intercepter aucune exception:

var sNumbers = new[] {"10", "20", "30"};
var dValues = sNumbers.Select(s => s.IsParseableAs<double>() ? double.Parse(s) : 0);

Méthode d'extension deux

public static TOutput ParseAs<TOutput>(this string value, TOutput defaultValue) {
    var type = typeof(TOutput);

    var tryParseMethod = type.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder,
        new[] { typeof(string), type.MakeByRefType() }, null);
    if (tryParseMethod == null) return defaultValue;

    var arguments = new object[] { value, null };
    return ((bool) tryParseMethod.Invoke(null, arguments)) ? (TOutput) arguments[1] : defaultValue;
}

Cette méthode d'extension vous permet d'analyser une string comme toute type possédant une méthode TryParse() et vous permet également de spécifier une valeur par défaut à renvoyer en cas d'échec de la conversion.

C'est mieux que d'utiliser l'opérateur ternaire avec la méthode d'extension ci-dessus, car la conversion n'est effectuée qu'une seule fois. Il utilise toujours la réflexion si ...

Exemples:

"123".ParseAs<int>(10);
"abc".ParseAs<int>(25);
"123,78".ParseAs<double>(10);
"abc".ParseAs<double>(107.4);
"2014-10-28".ParseAs<DateTime>(DateTime.MinValue);
"monday".ParseAs<DateTime>(DateTime.MinValue);

Sorties:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00

Si vous voulez savoir si une chaîne est un nombre, vous pouvez toujours essayer de l'analyser:

var numberString = "123";
int number;

int.TryParse(numberString , out number);

Notez que TryParse renvoie un bool, que vous pouvez utiliser pour vérifier si votre analyse a réussi.

6
Gabriel Florit

Double.TryParse

bool Double.TryParse(string s, out double result)
6
John Pirie

MISE À JOUR DE Kunal Noel Answer

stringTest.All(char.IsDigit);
// This returns true if all characters of the string are digits.

Mais, dans ce cas, nous avons que les chaînes vides passeront ce test, vous pouvez donc:

if (!string.IsNullOrEmpty(stringTest) && stringTest.All(char.IsDigit)){
   // Do your logic here
}
3
dayanrr91

Utilisez ces méthodes d’extension pour distinguer clairement entre une vérification si la chaîne est numérique et si la chaîne niquement contient 0-9 chiffres

public static class ExtensionMethods
{
    /// <summary>
    /// Returns true if string could represent a valid number, including decimals and local culture symbols
    /// </summary>
    public static bool IsNumeric(this string s)
    {
        decimal d;
        return decimal.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out d);
    }

    /// <summary>
    /// Returns true only if string is wholy comprised of numerical digits
    /// </summary>
    public static bool IsNumbersOnly(this string s)
    {
        if (s == null || s == string.Empty)
            return false;

        foreach (char c in s)
        {
            if (c < '0' || c > '9') // Avoid using .IsDigit or .IsNumeric as they will return true for other characters
                return false;
        }

        return true;
    }
}
2
userSteve

La meilleure solution flexible avec la fonction intégrée .net appelée- char.IsDigit. Cela fonctionne avec des nombres longs illimités. Il ne retournera vrai que si chaque caractère est un nombre numérique. Je l'ai souvent utilisée sans problème et avec une solution de nettoyage plus facile que j'ai jamais trouvée. J'ai fait un exemple de méthode.Son prêt à utiliser. De plus, j'ai ajouté une validation pour les entrées nulles et vides. Donc, la méthode est maintenant totalement à l'épreuve des balles

public static bool IsNumeric(string strNumber)
    {
        if (string.IsNullOrEmpty(strNumber))
        {
            return false;
        }
        else
        {
            int numberOfChar = strNumber.Count();
            if (numberOfChar > 0)
            {
                bool r = strNumber.All(char.IsDigit);
                return r;
            }
            else
            {
                return false;
            }
        }
    }
2
Liakat Hossain

Avec c # 7, vous pouvez intégrer la variable out:

if(int.TryParse(str, out int v))
{
}
2
Chad Kuehn
public static bool IsNumeric(this string input)
{
    int n;
    if (!string.IsNullOrEmpty(input)) //.Replace('.',null).Replace(',',null)
    {
        foreach (var i in input)
        {
            if (!int.TryParse(i.ToString(), out n))
            {
                return false;
            }

        }
        return true;
    }
    return false;
}
2
OMANSAK

J'espère que cela t'aides

string myString = "abc";
double num;
bool isNumber = double.TryParse(myString , out num);

if isNumber 
{
//string is number
}
else
{
//string is not a number
}
1
Arun

Tirez une référence à Visual Basic dans votre projet et utilisez sa méthode Information.IsNumeric telle que présentée ci-dessous pour pouvoir capturer des flottants ainsi que des entiers contrairement à la réponse ci-dessus qui ne capture que les ints.

    // Using Microsoft.VisualBasic;

    var txt = "ABCDEFG";

    if (Information.IsNumeric(txt))
        Console.WriteLine ("Numeric");

IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false
0
ΩmegaMan

Toutes les réponses sont utiles. Mais lorsque je recherchais une solution dont la valeur numérique était de 12 chiffres ou plus (dans mon cas), puis lors du débogage, j’ai trouvé la solution suivante utile:

double tempInt = 0;
bool result = double.TryParse("Your_12_Digit_Or_more_StringValue", out tempInt);

La variable résultat vous donnera vrai ou faux.

0
Nayan_07

Essayez les reges ci-dessous

new Regex(@"^\d{4}").IsMatch("6")    // false
new Regex(@"^\d{4}").IsMatch("68ab") // false
new Regex(@"^\d{4}").IsMatch("1111abcdefg") ```
0
Tahir