Identifizieren Sie, ob eine Zeichenfolge eine Zahl ist

731

Wenn ich diese Zeichenfolgen habe:

  1. "abc" = false

  2. "123" = true

  3. "ab2" = false

Gibt es einen Befehl wie IsNumeric()oder etwas anderes, der erkennen kann, ob eine Zeichenfolge eine gültige Zahl ist?

Gold
quelle
79
Aus ihren Beispielen können Sie ersehen, dass sie bedeuteten, wenn die gesamte Zeichenfolge eine Zahl darstellt.
Lucas
47
return str.All (Char.IsDigit);
Mohsen
13
str.All (Char.IsDigit) deklariert "3.14" als falsch sowie "-2" und "3E14".
Ganz zu schweigen
4
Dies hängt davon ab, welche Art von Nummer Sie überprüfen möchten. Für Ganzzahlen ohne Trennzeichen (dh Zeichenfolgen mit Dezimalstellen) funktioniert diese Prüfung und entspricht der akzeptierten und der in OP implizierten Antwort.
Alex Mazzariol
1
@ Lucas danke für Ihren Kommentar, Sie haben keine Ahnung, wie lange ich versucht habe, eine Zeichenfolge doppelt als int zu analysieren und mich zu fragen, warum es fehlgeschlagen ist ...
Novastorm

Antworten:

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

Update ab C # 7:

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

oder wenn Sie die Nummer nicht benötigen, können Sie den out-Parameter verwerfen

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

Die var s können durch ihre jeweiligen Typen ersetzt werden!

mqp
quelle
126
Allerdings würde ich double.TryParse verwenden, da wir wissen wollen, ob es überhaupt eine Zahl darstellt.
John Gietzen
5
Die Funktion gibt true zurück, wenn ich den String als "-123" oder "+123" übergebe. Ich verstehe, dass Ganzzahl positive und negative Werte hat. Wenn diese Zeichenfolge jedoch aus einem vom Benutzer eingegebenen Textfeld stammt, sollte false zurückgegeben werden.
user2323308
9
Dies ist eine gute Lösung, bis ein Benutzer einen Wert über -2.147.483.648 bis 2.147.483.647 eingibt und dies dann stillschweigend fehlschlägt
BlackTigerX
Versuchen Sie, 0,60 zu analysieren (das ist ein Komma!). Es ist eine ungültige Zahl, wird aber als 60 analysiert!
Paul Zahra
2
Ich bevorzuge Erweiterungsmethode für diese Prüfung: public static bool IsNumeric(this string text) { double _out; return double.TryParse(text, out _out); }
Hamid Naeemi
350

Dies gibt true zurück, wenn inputalle Zahlen sind. Ich weiß nicht, ob es besser ist als TryParse, aber es wird funktionieren.

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

Wenn Sie nur wissen möchten, ob eine oder mehrere Zahlen mit Zeichen gemischt sind, lassen Sie das ^ +und weg $.

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

Bearbeiten: Eigentlich denke ich, dass es besser ist als TryParse, weil eine sehr lange Zeichenfolge möglicherweise TryParse überlaufen könnte.

John M Gant
quelle
2
Ein für alle Mal den regulären Ausdruck zu erstellen, wäre jedoch viel effizienter.
Clément
2
@CFP +1 ... RegEx sind immer besser als übliche Funktionen, falls zutreffend!
MAXE
19
@ MAXE: Ich würde nicht zustimmen. Regelmäßige Ausdrucksprüfungen sind recht langsam, daher gibt es oft bessere Lösungen, wenn die Leistung berücksichtigt wird.
Michal B.
7
Bearbeiten: Sie können RegexOptions.Compiledals Parameter hinzufügen , wenn Sie Tausende von diesen für eine mögliche Geschwindigkeitssteigerung Regex.IsMatch(x.BinNumber, @"^\d+$", RegexOptions.Compiled)
ausführen
9
wird auch bei Negativen und Dingen mit.
Noctis
199

Sie können auch verwenden:

stringTest.All(char.IsDigit);

Es wird truefür alle numerischen Ziffern (nicht float) zurückgegeben und falsewenn die Eingabezeichenfolge eine alphanumerische Zeichenfolge ist.

Bitte beachten Sie : stringTestsollte keine leere Zeichenfolge sein, da dies den Test der Numerik bestehen würde.

Kunal Goel
quelle
20
Das ist sehr cool. Eines ist jedoch zu beachten: Eine leere Zeichenfolge besteht diesen Test als numerisch.
Dan-Gph
2
@ dan-gph: Ich bin froh, es gefällt dir. Ja du hast Recht. Ich habe den obigen Hinweis aktualisiert. Vielen Dank!
Kunal Goel
1
Dies funktioniert auch nicht für Dezimalfälle. Der richtige Test ist stringTest.All (l => char.IsDigit (l) || '.' == l || '-' == l);
Salman Hasrat Khan
Vielen Dank für Ihre Eingabe Salman. Um die Dezimalstelle einer Zeichenfolge gezielt zu überprüfen, können Sie - if (Decimal.TryParse (stringTest2, out value)) {/ * Yes, Decimal /} else {/ No, Not a Decimal * / }
Kunal Goel
6
Salman, es ist nicht so einfach - dies würde ..--..--als gültige Nummer gelten. Ganz sicher nicht.
Flynn1179
133

Ich habe diese Funktion mehrmals verwendet:

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;
}

Sie können aber auch verwenden;

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

Aus dem Benchmarking von isNumerischen Optionen

Alt-Text
(Quelle: aspalliance.com )

Alt-Text
(Quelle: aspalliance.com )

Nelson Miranda
quelle
80
Verweisen auf Microsoft.VisualBasic.dll aus der C # -App? eww: P
Lucas
Ich habe kein Problem mit "IsNumeric", es funktioniert gut. Sie können auch sehen, dass zwischen TryParse und IsNumeric nur ein geringer Effizienzunterschied besteht. Denken Sie daran, dass TryParse in 2.0 neu ist und es zuvor besser war, IsNumeric als jede andere Strategie zu verwenden.
Nelson Miranda
10
Nun, IsNumeric () von VB.NET verwendet intern double.TryParse () nach einer Reihe von Drehungen, die (unter anderem) für die VB6-Kompatibilität erforderlich sind. Wenn Sie keine Kompatibilität benötigen, ist double.TryParse () genauso einfach zu verwenden und erspart Ihnen die Verschwendung von Speicher, indem Sie Microsoft.VisualBasic.dll in Ihren Prozess laden.
Euro Micelli
4
Kurzer Hinweis: Die Verwendung eines regulären Ausdrucks ist viel schneller, wenn Sie es schaffen, die zugrunde liegende Finite-State-Maschine ein für alle Mal zu erstellen. Im Allgemeinen benötigt das Erstellen der Zustandsmaschine O (2 ^ n), wobei n die Länge des regulären Ausdrucks ist, während das Lesen O (k) ist, wobei k die Länge der gesuchten Zeichenfolge ist. Das Neuerstellen des regulären Ausdrucks führt also jedes Mal zu einer Verzerrung.
Clément
2
@Lucas Eigentlich gibt es ein paar wirklich nette Sachen, wie einen vollständigen CSV-Parser. Kein Grund, es nicht zu verwenden, wenn es dort vorhanden ist.
Nyerguds
32

Dies ist wahrscheinlich die beste Option in C #.

Wenn Sie wissen möchten, ob die Zeichenfolge eine ganze Zahl (Ganzzahl) enthält:

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

Die TryParse-Methode versucht, die Zeichenfolge in eine Zahl (Ganzzahl) zu konvertieren. Wenn dies erfolgreich ist, gibt sie true zurück und platziert die entsprechende Zahl in myInt. Wenn dies nicht möglich ist, wird false zurückgegeben.

Lösungen, die int.Parse(someString)die in anderen Antworten gezeigte Alternative verwenden, funktionieren, sind jedoch viel langsamer, da das Auslösen von Ausnahmen sehr teuer ist. TryParse(...)wurde der C # -Sprache in Version 2 hinzugefügt, und bis dahin hatten Sie keine Wahl. Jetzt tun Sie es: Sie sollten daher die Parse()Alternative vermeiden .

Wenn Sie Dezimalzahlen akzeptieren möchten, verfügt die Dezimalklasse auch über eine .TryParse(...)Methode. Ersetzen Sie int in der obigen Diskussion durch eine Dezimalstelle, und es gelten dieselben Prinzipien.

Euro Micelli
quelle
Warum ist TryParse besser als der Vergleich aller Zeichen mit ganzzahligen Zeichen?
Jimjim
25

Sie können immer die integrierten TryParse-Methoden für viele Datentypen verwenden, um festzustellen, ob die betreffende Zeichenfolge übergeben wird.

Beispiel.

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

Ergebnis wäre dann = True

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

Ergebnis wäre dann = Falsch

TheTXI
quelle
Ich glaube, ich habe das mehr in der VB-Syntax als in C # getan, aber es gelten die gleichen Regeln.
TheTXI
22

Falls Sie int.Parse oder double.Parse nicht verwenden möchten, können Sie Ihre eigenen mit so etwas rollen:

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;
    }
}
BKostenlos
quelle
7
Was wäre, wenn sie nur ganze Zahlen bedeuten würden? Was ist mit Gebietsschemas, in denen '.' ist das Gruppentrennzeichen nicht das Komma (zB pt-Br)? was ist mit negativen Zahlen? Gruppentrennzeichen (Kommas in Englisch)? Währungssymbole? TryParse () kann all dies nach Bedarf mit NumberStyles und IFormatProvider verwalten.
Lucas
Ooh ja, ich mag die All-Version besser. Ich habe diese Erweiterungsmethode noch nie benutzt, guter Anruf. Obwohl es an ToCharArray () sein sollte. Alle (..). Was Ihren zweiten Punkt betrifft, höre ich Sie, weshalb ich vorangestellt habe, wenn Sie int.Parse nicht verwenden möchten .... (von dem ich annehme, dass es mehr Overhead hat ...)
BFree
11
1.3.3.8.5 ist jedoch keine wirkliche Zahl, während 1.23E5 eine Zahl ist.
Clément
4
Die Logik ist fehlerhaft. -1
Russel Yang
1
@Lucas Ich stimme zu, dass TryParse mehr handhabt, aber manchmal wird das nicht benötigt. Ich muss nur meine Kreditkartennummernfelder validieren (die nur Ziffern haben können). Diese Lösung ist fast definitiv schneller als das Parsen.
Millie Smith
14

Wenn Sie ein breiteres Spektrum von Zahlen erfassen möchten, à la PHP is_numeric , können Sie Folgendes verwenden:

// 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 );
}

Gerätetest:

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 );
}

Beachten Sie, dass ein numerischer Wert nicht bedeutet, dass er in einen numerischen Typ konvertiert werden kann. Beispielsweise "999999999999999999999999999999.9999999999"handelt es sich um einen perfekt gültigen numerischen Wert, der jedoch nicht in einen numerischen .NET-Typ passt (dh keinen, der in der Standardbibliothek definiert ist).

JDB erinnert sich noch an Monica
quelle
Ich versuche hier nicht, ein kluger Alec zu sein, aber dies scheint für die Zeichenfolge "0" fehlzuschlagen. Mein Regex existiert nicht. Gibt es dafür eine einfache Optimierung? Ich bekomme "0" und möglicherweise "0.0" und sogar "-0.0" als mögliche gültige Zahlen.
Steve Hibbert
@SteveHibbert - Jeder weiß, dass "0" keine Zahl ist! Im Ernst ... hat die Regex auf 0 angepasst.
JDB erinnert sich noch an Monica
Hmmm, bin ich es oder wird "0" immer noch nicht als numerisch erkannt?
Steve Hibbert
1
Da ich faul und regex-ignorant bin, habe ich den obigen Code ausgeschnitten, der anscheinend die Änderung des Typs "0.0" enthält. Ich habe einen Test ausgeführt, um zu überprüfen, ob eine Zeichenfolge "0" mit .IsNumeric () ausgeführt wird und ob false zurückgegeben wird. Ich denke, dass der Oktaltest für alles, was zwei numerische Zeichen hat, wobei das erste Null ist (und das zweite null bis sieben), wahr ist, aber nur für eine große, fette, einsame Null allein falsch zurückgibt. Wenn Sie "0" mit dem obigen Code testen, werden Sie falsch? Entschuldigung, wenn ich mehr Regex wüsste, könnte ich besseres Feedback geben. Muss nachlesen.
Steve Hibbert
1
! Doh! Lesen Sie einfach Ihren Kommentar oben noch einmal durch. Ich hatte das zusätzliche Sternchen übersehen und nur die Dezimallinie aktualisiert. Damit haben Sie Recht, "0" IsNumeric. Ich entschuldige mich für das Faffing und danke Ihnen vielmals für das Update. Ich hoffe, es hilft auch anderen. Herzlichen Dank.
Steve Hibbert
14

Ich weiß, dass dies ein alter Thread ist, aber keine der Antworten hat es wirklich für mich getan - entweder ineffizient oder nicht für eine einfache Wiederverwendung gekapselt. Ich wollte auch sicherstellen, dass false zurückgegeben wird, wenn die Zeichenfolge leer oder null ist. TryParse gibt in diesem Fall true zurück (eine leere Zeichenfolge verursacht beim Parsen als Zahl keinen Fehler). Also, hier ist meine String-Erweiterungsmethode:

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);
    }
}

Einfach zu benutzen:

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

Wenn Sie andere Arten von Zahlen testen möchten, können Sie den 'Stil' angeben. Um eine Zahl mit einem Exponenten zu konvertieren, können Sie Folgendes verwenden:

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

Oder um eine mögliche Hex-Zeichenfolge zu testen, können Sie Folgendes verwenden:

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

Der optionale Parameter 'Kultur' kann auf die gleiche Weise verwendet werden.

Es ist begrenzt, weil es nicht in der Lage ist, Zeichenfolgen zu konvertieren, die zu groß sind, um in einem Double enthalten zu sein. Dies ist jedoch eine begrenzte Anforderung, und ich denke, wenn Sie mit Zahlen arbeiten, die größer als diese sind, benötigen Sie wahrscheinlich eine zusätzliche spezialisierte Nummernverarbeitung funktioniert sowieso.

Cyberspy
quelle
2
Funktioniert hervorragend, außer dass Double.TryParse NumberStyles.HexNumber nicht unterstützt. Siehe MSDN Double.TryParse. Gibt es einen Grund, warum Sie TryParse verwenden, bevor Sie nach IsNullOrWhiteSpace suchen? TryParse gibt false zurück, wenn IsNullOrWhiteSpace nicht wahr ist.
Harald Coppoolse
10

Mit TryParse können Sie bestimmen, ob die Zeichenfolge in eine Ganzzahl analysiert werden kann.

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

Der Boolesche Wert sagt Ihnen, ob es funktioniert hat oder nicht.

Craig
quelle
9

Wenn Sie überprüfen möchten, ob eine Zeichenfolge eine Zahl ist (ich gehe davon aus, dass es sich um eine Zeichenfolge handelt, denn wenn es sich um eine Zahl handelt, wissen Sie, dass es eine ist).

  • Ohne Regex und
  • Verwenden Sie so viel wie möglich den Code von Microsoft

Sie könnten auch tun:

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

Dies wird sich um die üblichen Gemeinheiten kümmern:

  • Minus (-) oder Plus (+) am Anfang
  • enthält DezimalzeichenBigIntegers analysiert keine Zahlen mit Dezimalstellen. (Also: BigInteger.Parse("3.3")wird eine Ausnahme auslösen und TryParsefür dasselbe wird false zurückgegeben)
  • keine lustigen Ziffern
  • deckt Fälle ab, in denen die Anzahl größer ist als die übliche Verwendung von Double.TryParse

Sie müssen einen Verweis auf Ihre Klasse hinzufügen System.Numericsund diese using System.Numerics;an der Spitze haben (nun, der zweite ist ein Bonus, denke ich :)

Noctis
quelle
8

Ich denke, diese Antwort wird nur zwischen all den anderen verloren gehen, aber trotzdem geht es weiter.

Ich landete in dieser Frage über Google, weil ich überprüfen wollte , ob eine stringwar numericso , dass ich nur verwenden könnte double.Parse("123")anstelle des TryParse()Verfahrens.

Warum? Weil es ärgerlich ist, eine outVariable deklarieren und das Ergebnis überprüfen zu müssen, TryParse()bevor Sie wissen, ob die Analyse fehlgeschlagen ist oder nicht. Ich möchte das verwenden ternary operator, um zu überprüfen, ob das stringist, numericalund es dann einfach im ersten ternären Ausdruck analysieren oder einen Standardwert im zweiten ternären Ausdruck angeben.

So was:

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

Es ist nur viel sauberer als:

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

Ich habe ein paar extension methodsfür diese Fälle gemacht:


Erweiterungsmethode eins

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);
}

Beispiel:

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

Da IsParseableAs()versucht wird, die Zeichenfolge als geeigneten Typ zu analysieren, anstatt nur zu überprüfen, ob die Zeichenfolge "numerisch" ist, sollte sie ziemlich sicher sein. Und Sie können es sogar für nicht numerische Typen verwenden, die eine TryParse()Methode haben, wie z DateTime.

Die Methode verwendet Reflection und Sie rufen die TryParse()Methode am Ende zweimal auf, was natürlich nicht so effizient ist, aber nicht alles muss vollständig optimiert werden. Manchmal ist die Bequemlichkeit einfach wichtiger.

Diese Methode kann auch verwendet werden, um eine Liste numerischer Zeichenfolgen einfach in eine Liste doubleoder einen anderen Typ mit einem Standardwert zu analysieren, ohne Ausnahmen abfangen zu müssen:

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

Erweiterungsmethode zwei

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;
}

Mit dieser Erweiterungsmethode können Sie a stringals typeeine TryParse()Methode mit einer Methode analysieren und einen Standardwert angeben, der zurückgegeben werden soll, wenn die Konvertierung fehlschlägt.

Dies ist besser als die Verwendung des ternären Operators mit der obigen Erweiterungsmethode, da die Konvertierung nur einmal durchgeführt wird. Es wird immer noch Reflexion verwendet ...

Beispiele:

"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);

Ausgänge:

123
25
123,78
107,4
28.10.2014 00:00:00
01.01.0001 00:00:00
Hein Andre Grønnestad
quelle
4
Ich glaube, Sie haben vielleicht einen der ineffizientesten Ansätze erfunden, die ich bisher gesehen habe. Sie analysieren die Zeichenfolge nicht nur zweimal (falls sie analysierbar ist), sondern rufen auch mehrmals Reflexionsfunktionen auf, um dies zu tun. Und am Ende speichern Sie nicht einmal Tastenanschläge mit der Erweiterungsmethode.
JDB erinnert sich noch an Monica
Vielen Dank, dass Sie nur das wiederholen, was ich selbst im vorletzten Absatz geschrieben habe. Auch wenn Sie mein letztes Beispiel berücksichtigen, speichern Sie mit dieser Erweiterungsmethode definitiv Tastenanschläge. Diese Antwort behauptet nicht, eine magische Lösung für ein Problem zu sein, sondern lediglich ein Codebeispiel. Verwenden Sie es oder verwenden Sie es nicht. Ich denke, es ist praktisch, wenn es richtig verwendet wird. Und es enthält Beispiele sowohl für Erweiterungsmethoden als auch für Reflexionen. Vielleicht kann jemand daraus lernen.
Hein Andre Grønnestad
5
Hast du es versucht var x = double.TryParse("2.2", new double()) ? double.Parse("2.2") : 0.0;?
JDB erinnert sich noch an Monica
2
Ja, und es funktioniert nicht. Argument 2 must be passed with the 'out' keywordund wenn Sie outso gut angeben, wie newSie bekommen A ref or out argument must be an assignable variable.
Hein Andre Grønnestad
1
Leistung TryParse ist besser als alle hier gezeigten. Ergebnisse: TryParse 8 Regex 20 PHP IsNumeric 30 Reflections TryParse 31 Testcode dotnetfiddle.net/x8GjAF
prampe
7

Wenn Sie wissen möchten, ob eine Zeichenfolge eine Zahl ist, können Sie sie jederzeit analysieren:

var numberString = "123";
int number;

int.TryParse(numberString , out number);

Beachten Sie, dass TryParsea zurückgegeben wird bool, mit dem Sie überprüfen können, ob das Parsen erfolgreich war.

Gabriel Florit
quelle
7

Double.TryParse

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

quelle
4

UPDATE von Kunal Noel Antwort

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

In diesem Fall bestehen jedoch leere Zeichenfolgen diesen Test. Sie können also:

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

Die beste flexible Lösung mit der in .net integrierten Funktion namens- char.IsDigit. Es funktioniert mit unbegrenzt langen Nummern. Es wird nur true zurückgegeben, wenn jedes Zeichen eine numerische Zahl ist. Ich habe es oft ohne Probleme und mit einer viel saubereren Lösung verwendet, die ich jemals gefunden habe. Ich habe eine Beispielmethode erstellt. Sie ist einsatzbereit. Zusätzlich habe ich eine Validierung für null und leere Eingaben hinzugefügt. Damit ist die Methode jetzt absolut kugelsicher

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;
            }
        }
    }
Liakat
quelle
2

Mit c # 7 können Sie die out-Variable inline:

if(int.TryParse(str, out int v))
{
}
Chad Kuehn
quelle
2

Verwenden Sie diese Erweiterungsmethoden, um klar zwischen einer Prüfung zu unterscheiden, ob die Zeichenfolge numerisch ist und ob die Zeichenfolge nur 0-9 Ziffern enthält

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;
    }
}
userSteve
quelle
2
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;
}
OMANSAK
quelle
1

Hoffe das hilft

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

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

Ziehen Sie in Ihrem Projekt einen Verweis auf Visual Basic ein und verwenden Sie die unten gezeigte Information.IsNumeric-Methode, um Floats und Ganzzahlen zu erfassen, im Gegensatz zu der obigen Antwort, die nur Ints abfängt.

    // Using Microsoft.VisualBasic;

    var txt = "ABCDEFG";

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

IsNumeric("12.3"); // true
IsNumeric("1"); // true
IsNumeric("abc"); // false
ΩmegaMan
quelle
Ein mögliches Problem bei diesem Ansatz besteht darin, dass IsNumericeine Zeichenanalyse der Zeichenfolge durchgeführt wird. Eine Nummer wie 9999999999999999999999999999999999999999999999999999999999.99999999999wird also als registriert True, obwohl es keine Möglichkeit gibt, diese Nummer mit einem numerischen Standardtyp darzustellen.
JDB erinnert sich noch an Monica
0

Probieren Sie die folgenden Zeilen aus

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

Alle Antworten sind nützlich. Bei der Suche nach einer Lösung mit einem numerischen Wert von 12 Stellen oder mehr (in meinem Fall) und beim Debuggen fand ich die folgende Lösung hilfreich:

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

Die Ergebnisvariable gibt Ihnen wahr oder falsch.

Nayan_07
quelle
-7
//To my knowledge I did this in a simple way
static void Main(string[] args)
{
    string a, b;
    int f1, f2, x, y;
    Console.WriteLine("Enter two inputs");
    a = Convert.ToString(Console.ReadLine());
    b = Console.ReadLine();
    f1 = find(a);
    f2 = find(b);

    if (f1 == 0 && f2 == 0)
    {
        x = Convert.ToInt32(a);
        y = Convert.ToInt32(b);
        Console.WriteLine("Two inputs r number \n so that addition of these text box is= " + (x + y).ToString());
    }
    else
        Console.WriteLine("One or two inputs r string \n so that concatenation of these text box is = " + (a + b));
    Console.ReadKey();
}

static int find(string s)
{
    string s1 = "";
    int f;
    for (int i = 0; i < s.Length; i++)
       for (int j = 0; j <= 9; j++)
       {
           string c = j.ToString();
           if (c[0] == s[i])
           {
               s1 += c[0];
           }
       }

    if (s == s1)
        f = 0;
    else
        f = 1;

    return f;
}
Vino
quelle
1
Vier Abstimmungen, aber niemand hat gesagt warum? Ich nehme an, es liegt daran, dass TryParse / Parse eine bessere Option wäre, aber nicht jeder, der hierher kommt, wird das wissen.
njplumridge
2
Sie haben es so kompliziert gemacht, dass sogar C-Programmierer sagen würden "
Meine Güte
1. Es gibt keinen Grund, ZWEI Nummern von der Konsole zu lesen und hinzuzufügen. Woher die Zeichenfolge kommt, ist sowieso irrelevant, daher gibt es keinen Grund, überhaupt etwas von der Konsole zu lesen.
Algoman
2. Die Variable für f ist nicht erforderlich. Sie können 0 oder 1 direkt zurückgeben. Wenn Sie eine einzelne Rückgabe wünschen, können Sie dafür den ternären Operator verwenden. int ist auch der falsche Rückgabetyp für find, es sollte bool sein und Sie könnten s == s1
Algoman
3. Sie kopieren die Ziffern von s nach s1 und vergleichen dann s mit s1. Dies ist viel langsamer als es sein muss. Warum setzen Sie die innere Schleife fort, auch wenn c [0] == s [i] passiert ist? Erwarten Sie, dass s [i] auch anderen Ziffern entspricht?
Algoman