Laden...

Effizienter Weg um String auf Nummer zu prüfen?

Erstellt von math55 vor 15 Jahren Letzter Beitrag vor 15 Jahren 3.581 Views
math55 Themenstarter:in
314 Beiträge seit 2007
vor 15 Jahren
Effizienter Weg um String auf Nummer zu prüfen?

Hallo, momentan prüfe ich, ob ein string eine Nummer ist, indem ich nen Regex nehme:


if(Regex.isMatch(meinString, "^\\d+$"))
    //ist eine Nummer

Gibt es da nicht eine eingebaute Variante der Art:


if(myString.IsNumber())
    //ist eine Nummer

Wie macht man das üblicherweise in C# 3.x?

Danke 🙂

1.200 Beiträge seit 2007
vor 15 Jahren

Ich find regex ganz ok, du könntest aber auch die TryParse Methoden benutzen.

Z.B. double.TryParse, Integer.TryParse etc.

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

K
593 Beiträge seit 2007
vor 15 Jahren

Hallo,

wenn es nur darum geht ob der String eine Zahl ist und kein nur Zahlen sind kannst du es z.b. mit Int.TryParse probieren. Das prüft ob es Zahlen sind. Sobald ein Buchstabe oder etwas anderes dabei ist gibt er ein False 🙂

Gruß Daniel

math55 Themenstarter:in
314 Beiträge seit 2007
vor 15 Jahren

Was wäre denn fixer?

Grüße

104 Beiträge seit 2004
vor 15 Jahren

Ich habe es grade mal kurz getestet, TryParse ist etwa 7 mal schneller.

Wenn du den RegEx-Ausdruck compilierst ist TryParse nurnoch um das 1.5-fache schneller.

Schaut mal im IRC vorbei:
Server: irc.euirc.net
Channel: #C#

math55 Themenstarter:in
314 Beiträge seit 2007
vor 15 Jahren

Also wie wäre dann mein TryParse?


if (int.TryParse(myString)) // ist nur eine Nummer die klein ist, int reicht hier aus
    //ist eine Nummer

Korrekt?

104 Beiträge seit 2004
vor 15 Jahren

Int32 value;


if (Int32.TryParse(anyString, out value)) myDataClass.Proprty = value;

So würde es in etwa aussehen. Kommt halt drauf an was du machen willst.

Schaut mal im IRC vorbei:
Server: irc.euirc.net
Channel: #C#

math55 Themenstarter:in
314 Beiträge seit 2007
vor 15 Jahren

Ich möchte lediglich schaun, ob ein String eine Nummer ist, darum brauch ich den out Parameter nicht.

Grüße

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo math55,

beim Aufruf einer Methode müssen alle (out-)Parameter angegeben werden, selbst wenn man die nicht benötigt.

herbivore

L
53 Beiträge seit 2007
vor 15 Jahren

Wobei es noch einen Unterschied zwischen deinem RegEx und dem Int32.TryParse gibt: Dein RegEx prüft, ob der String nur Zahlen enthält - Int32.TryParse prüft, ob der String einen gültigen 32-bit Integer enthält.
Konkret bedeutet das: Int32.TryParse liefert auch bei negativen Werten ein true zurück und Int32.TryParse liefert bei Zahlen, die außerhalb des Int32-Zahlenraums liegen (z.B. 123456789012345678901234567890) ein false zurück.

888 Beiträge seit 2007
vor 15 Jahren

Ich mach das immer wie folgt:


        /// <summary>
        /// Check if a string a digit
        /// </summary>
        /// <param name="i_candite">candidate to check</param>
        /// <returns>isDigit?</returns>
        private bool isDigit(string i_candite)
        {
            try
            {
                Convert.ToInt64(i_candite);
                return true;
            }
            catch
            {
                return false;
            }
        }

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Joetempes,

das ist leider kein guter Weg. Es ist besser TryParse statt Parse zu verwenden. Es ist extra dafür da.

herbivore

math55 Themenstarter:in
314 Beiträge seit 2007
vor 15 Jahren

Ja, funktioniert prima 🙂

Danke

U
1.688 Beiträge seit 2007
vor 15 Jahren

Hallo,

es wäre ja auch prinzipiell denkbar, den String Zeichen für Zeichen durchzugehen (mit []) und nachzuschauen, ob das Zeichen ≥'0' und ≤'9' ist.
Über die (relative) Geschwindigkeit kann ich jetzt keine Aussage machen. Ich glaube aber mich zu erinnern, dass es effektiver ist, den String vorher in ein char-Array zu kopieren...

An sich sollte diese Prüfung etwas besser sein, da der ganze hier überflüssige Kram vom Parsen weggelassen wird. Allerdings hab ich grad gesehen, dass TryParse den String per char* in einem unsafe-Block durchgeht - das müsste man dann für maximale Geschwindigkeit natürlich noch tun.

3.971 Beiträge seit 2006
vor 15 Jahren

Hallo ujr,
das funktioniert nicht, da du auch Dezimaltrennzeichen, Tausendertrenner, Negativzeichen usw. prüfen müsstest und das ist je nach Kultur unterschiedlich und Microsoft hat die Funktionen TryParse und Parse. bereits fertig implementiert.

Eventuell gäbe es noch die IsNumeric-Funktion von VB.NET um zu prüfen, ob es sich um eine Zahl handelt.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

U
1.688 Beiträge seit 2007
vor 15 Jahren

Hallo kleines_eichhoernchen,

auch Dezimaltrennzeichen, Tausendertrenner, Negativzeichen usw. prüfen

Hmmm - Ausgangspunkt war der reguläre Ausdruck "^\d+$", der auf Ziffern prüft. Da ist das von mir beschriebene Vorgehen funktionell äquivalent.

Für den allgemeinen Fall einer Zahl hast Du natürlich recht - es ist wenig sinnvoll, TryParse erneut zu implementieren. Es gibt dann lediglich noch die Ausnahmen der "BigInteger", wie weiter oben auch schon mal erwähnt.

Gelöschter Account
vor 15 Jahren

Hallo Joetempes,

ich kann dir Guide to C# -> Styleguide -> Exceptions empfehlen.

@topic:
egal wie ihr es dreht. TryParse ist an dieser stelle das mittel der wahl. alles andere ist entwder eine vollständige reimplementation von tryparse oder beinhaltet fehler.

und convert soll man nur benutzten, wenn man sich sicher ist, das es nicht fehlschlägt.