Qual è l'equivalente in C # di NaN o IsNumeric?


103

Qual è il modo più efficiente per testare una stringa di input se contiene un valore numerico (o al contrario Non un numero)? Immagino di poter usare Double.Parseo una regex (vedi sotto) ma mi chiedevo se ci fosse un modo integrato per farlo, come javascript NaN()o IsNumeric()(era VB, non ricordo?).

public static bool IsNumeric(this string value)
{
    return Regex.IsMatch(value, "^\\d+$");
}

Risposte:


176

Questo non ha l'overhead di regex

double myNum = 0;
String testVar = "Not A Number";

if (Double.TryParse(testVar, out myNum)) {
  // it is a number
} else {
  // it is not a number
}

Per inciso, tutti i tipi di dati standard, con l'eccezione lampante dei GUID, supportano TryParse.

update
secretwep ha evidenziato che il valore "2345" supererà il test precedente come numero. Tuttavia, se è necessario assicurarsi che tutti i caratteri all'interno della stringa siano cifre, è necessario adottare un altro approccio.

esempio 1 :

public Boolean IsNumber(String s) {
  Boolean value = true;
  foreach(Char c in s.ToCharArray()) {
    value = value && Char.IsDigit(c);
  }

  return value;
}

o se vuoi essere un po 'più stravagante

public Boolean IsNumber(String value) {
  return value.All(Char.IsDigit);
}

aggiornamento 2 (da @stackonfire per gestire stringhe nulle o vuote)

public Boolean IsNumber(String s) { 
    Boolean value = true; 
    if (s == String.Empty || s == null) { 
        value=false; 
    } else { 
        foreach(Char c in s.ToCharArray()) { 
            value = value && Char.IsDigit(c); 
        } 
    } return value; 
}

Se necessario, puoi racchiudere il codice sopra in un metodo di utilità più utile come public static bool IsInteger (stringa sMaybeANumber)
Gishu

@Gishu: Hai ragione se tutto ciò che ti interessa è se il numero può convertire.
NotMe

2
L'unico problema con questo è che l' Numberoggetto in Javascript è un float o un numero intero, quindi cambiare in double.TryParse sarebbe un equivalente più esatto
Chris S

7
Potresti voler fare attenzione con questo dato che le stringhe "NaN" e "Infinity" analizzano a double, ma molti le considererebbero non numeriche.
Mike Zboray

1
Un esempio 1 corretto per gestire stringhe nulle o vuote, che altrimenti causavano la restituzione erronea di IsNumber a true: public Boolean IsNumber(String s) { Boolean value = true; if (s == String.Empty || s == null) { value=false; } else { foreach(Char c in s.ToCharArray()) { value = value && Char.IsDigit(c); } } return value; }
stackonfire

41

Preferisco qualcosa di simile, ti permette di decidere cosa NumberStyleprovare.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}

7
+1 per essere stata l'unica persona finora a Double.TryParse invece di Int.TryParse :)
johnc

Questo è anche, ovviamente, quasi un metodo di estensione.
Anthony Mastrean

19

In aggiunta alle precedenti risposte corrette è probabilmente opportuno sottolineare che "Not a Number" (NaN) nel suo utilizzo generale non è equivalente a una stringa che non può essere valutata come valore numerico. NaN è generalmente inteso come un valore numerico utilizzato per rappresentare il risultato di un calcolo "impossibile", in cui il risultato è indefinito. A questo proposito, direi che l'utilizzo di Javascript è leggermente fuorviante. In C # NaN è definito come una proprietà dei tipi numerici singoli e doppi e viene utilizzato per fare riferimento esplicitamente al risultato dell'immersione zero per zero. Altre lingue lo usano per rappresentare diversi valori "impossibili".


11

So che è stato risposto in molti modi diversi, con estensioni ed esempi lambda, ma una combinazione di entrambi per la soluzione più semplice.

public static bool IsNumeric(this String s)
{
    return s.All(Char.IsDigit);
}

o se utilizzi Visual Studio 2015 (C # 6.0 o versione successiva)

public static bool IsNumeric(this String s) => s.All(Char.IsDigit);

Fantastico C # 6 su una riga. Ovviamente questo è limitato perché verifica solo i caratteri numerici.

Per usarlo, basta avere una stringa e chiamare il metodo su di essa, ad esempio:

bool IsaNumber = "123456".IsNumeric();

1
Per gli utenti che non hanno familiarità con i metodi di estensione , potrebbe essere utile includere alcune informazioni in più (o almeno la classe statica circostante per fornire un esempio più completo).
johnnyRose

Non mi piace questa soluzione perché restituirà false per i numeri con un decimale. Potrebbe essere utile per i numeri interi, ma se è quello che vuoi usarlo per il metodo dovrebbe essere rinominato IsInteger
technoman23

5

Sì, IsNumeric è VB. Di solito le persone usano il metodo TryParse (), sebbene sia un po 'goffo. Come hai suggerito, puoi sempre scrivere il tuo.

int i;
if (int.TryParse(string, out i))
{

}

5

Mi piace il metodo di estensione, ma non mi piace lanciare eccezioni se possibile. Ho optato per un metodo di estensione che prende la migliore delle 2 risposte qui.

    /// <summary>
    /// Extension method that works out if a string is numeric or not
    /// </summary>
    /// <param name="str">string that may be a number</param>
    /// <returns>true if numeric, false if not</returns>
    public static bool IsNumeric(this String str)
    {
        double myNum = 0;
        if (Double.TryParse(str, out myNum))
        {
            return true;
        }
        return false;
    }

4

È comunque possibile utilizzare la funzione Visual Basic in C #. L'unica cosa che devi fare è seguire le mie istruzioni mostrate di seguito:

  1. Aggiungi il riferimento alla libreria di Visual Basic facendo clic con il pulsante destro del mouse sul tuo progetto e selezionando "Aggiungi riferimento":

inserisci qui la descrizione dell'immagine

  1. Quindi importalo nella tua classe come mostrato di seguito:

    using Microsoft.VisualBasic;

  2. Quindi usalo dove vuoi come mostrato di seguito:

                if (!Information.IsNumeric(softwareVersion))
            {
                throw new DataException(string.Format("[{0}] is an invalid App Version!  Only numeric values are supported at this time.", softwareVersion));
            }

Spero, questo aiuta e buona fortuna!


2
Anche se non consiglierei questo metodo, è una risposta corretta. Non sono sicuro del motivo per cui è stato downvotato, e poiché non è stato spiegato neanche il motivo, ho votato per contrastarlo :-)
Abacus

4

VB ha la IsNumericfunzione. Puoi fare riferimento Microsoft.VisualBasic.dlle usarlo.


Puoi ottenere quel metodo VB solo nelle versioni> 2.0 di .net?
Ed S.

@ ChuckD: Questo è soggettivo. Ti riferisci a librerie esterne che si occupano di json o scrivi tutto per analizzare json da solo?
shahkalpesh

@ChuckD: Risparmiami le sciocchezze e spiega perché è una schifezza. Per me, è solo un'altra dll che contiene alcune classi / funzioni utili.
shahkalpesh

@ChuckD Penso che tu sia irragionevole qui. La funzione fa il lavoro, è facile da importare e non è un grosso problema.
Bug il

1
@ChuckD potresti voler iniziare con critiche costruttive invece di iniziare con L' importazione di VisualBasic.dll per IsNumeric dovrebbe farti licenziare! il che chiaramente rialzerà qualcuno. La risposta risale al '09 e anche adesso può essere utile ad alcune persone.
Bugs

4

Semplice estensione:

public static bool IsNumeric(this String str)
{
    try
    {
        Double.Parse(str.ToString());
        return true;
    }
    catch {
    }
    return false;
}

se il parametro di input è una stringa perché usare .ToString ()?
technoman23

Questa risposta è buona perché elimina la variabile spazzatura necessaria per il metodo TryParse, che viene utilizzato in risposte come la soluzione di NER1808.
technoman23

3
public static bool IsNumeric(string anyString)
{
    if (anyString == null)
    {
        anyString = "";
    }

    if (anyString.Length > 0)
    {
        double dummyOut = new double();
        System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US", true);
        return Double.TryParse(anyString, System.Globalization.NumberStyles.Any, cultureInfo.NumberFormat, out dummyOut);
    }
    else
    {
        return false;
    }
}

3

Forse questa è una funzionalità C # 3, ma potresti usare double.NaN.


2

In realtà, Double.NaNè supportato in tutte le versioni .NET 2.0 e successive.


2

Stavo usando lo snippet di Chris Lively (risposta selezionata) incapsulato in una funzione bool come il suggerimento di Gishu per un anno o due. L'ho usato per assicurarmi che alcune stringhe di query fossero solo numeriche prima di procedere con un'ulteriore elaborazione. Ho iniziato a ricevere alcune stringhe di query errate che la risposta contrassegnata non stava gestendo, in particolare, ogni volta che una virgola veniva passata dopo un numero come "3645" (restituito vero). Questa è la mod risultante:

   static public bool IsNumeric(string s)
   {
      double myNum = 0;
      if (Double.TryParse(s, out myNum))
      {
         if (s.Contains(",")) return false;
         return true;
      }
      else
      {
         return false;
      }
   }

+1 per essere interessante. Immagino sia più una questione di utilizzo. In altre parole, se vuoi solo assicurarti che il valore possa essere convertito in un numero senza generare un errore, la mia risposta originale è buona. Tuttavia, se sei più preoccupato che tutti i caratteri all'interno della stringa siano effettivamente cifre, è necessario un approccio completamente diverso
NotMe

Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out myNum)
Sam Harwell

0

Ho una versione leggermente diversa che restituisce il numero. Immagino che nella maggior parte dei casi dopo aver testato la stringa dovresti utilizzare il numero.

public bool IsNumeric(string numericString, out Double numericValue)
{
    if (Double.TryParse(numericString, out numericValue))
        return true;
    else
        return false;
}

0

Questa è una versione modificata della soluzione proposta dall'onorevole Siir. Trovo che l'aggiunta di un metodo di estensione sia la soluzione migliore per il riutilizzo e la semplicità nel metodo di chiamata.

public static bool IsNumeric(this String s)
{
    try { double.Parse(s); return true; }
    catch (Exception) { return false; }
}

Ho modificato il corpo del metodo per adattarlo a 2 righe e ho rimosso l'implementazione non necessaria .ToString (). Per coloro che non hanno familiarità con i metodi di estensione, ecco come implementare:

Crea un file di classe chiamato ExtensionMethods . Incolla questo codice:

using System;
using System.Collections.Generic;
using System.Text;

namespace YourNameSpaceHere
{
    public static class ExtensionMethods
    {
        public static bool IsNumeric(this String s)
        {
            try { double.Parse(s); return true; }
            catch (Exception) { return false; }
        }
    }
}

Sostituisci YourNameSpaceHere con il tuo NameSpace effettivo. Salvare le modifiche. Ora puoi utilizzare il metodo di estensione ovunque nella tua app:

bool validInput = stringVariable.IsNumeric();

Nota: questo metodo restituirà true per numeri interi e decimali, ma restituirà false se la stringa contiene una virgola. Se si desidera accettare l'input con virgole o simboli come "$", suggerirei di implementare un metodo per rimuovere prima quei caratteri, quindi verificare se IsNumeric.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.