Freigeben über


Analysieren numerischer Zeichenfolgen in .NET

Alle numerischen Typen verfügen über zwei statische Analysemethoden, Parse und TryParse, die Sie verwenden können, um die Zeichenfolgendarstellung einer Zahl in einen numerischen Typ zu konvertieren. Mit diesen Methoden können Sie Zeichenfolgen analysieren, die mithilfe von Formatzeichenfolgen erstellt wurden, die in standardmäßigen numerischen Formatzeichenfolgen und benutzerdefinierten numerischen Formatzeichenfolgen dokumentiert wurden. Standardmäßig können die Methoden Parse und TryParse Zeichenfolgen, die nur integrale Dezimalziffern enthalten, erfolgreich in ganzzahlige Werte konvertieren. Sie können erfolgreich Zeichenfolgen konvertieren, die Ganz- und Bruchdezimalstellen sowie Gruppentrennzeichen und ein Dezimaltrennzeichen enthalten, in Gleitkommawerte. Die Parse Methode löst eine Ausnahme aus, wenn der Vorgang fehlschlägt, während die TryParse Methode false zurückgibt.

Hinweis

Ab .NET 7 implementieren die numerischen Typen in .NET auch die System.IParsable<TSelf>-Schnittstelle, welche die Methoden IParsable<TSelf>.Parse und IParsable<TSelf>.TryParse definiert.

Syntaxanalyse und Formatierungsanbieter

In der Regel unterscheiden sich die Zeichenfolgendarstellungen numerischer Werte je nach Kultur. Elemente numerischer Zeichenfolgen wie Währungssymbole, Gruppentrennzeichen (oder Tausendertrennzeichen) und Dezimaltrennzeichen variieren je nach Kultur. Die Analysemethoden verwenden entweder implizit oder explizit einen Formatanbieter, der diese kulturspezifischen Variationen erkennt. Wenn bei einem Aufruf der Parse- oder TryParse-Methode kein Formatanbieter angegeben ist, wird der mit der aktuellen Kultur verknüpfte Formatanbieter (das von der NumberFormatInfo.CurrentInfo-Eigenschaft zurückgegebene NumberFormatInfo-Objekt) verwendet.

Ein Formatanbieter wird durch eine IFormatProvider Implementierung dargestellt. Diese Schnittstelle verfügt über ein einzelnes Element, die GetFormat Methode, deren einzelner Parameter ein Type Objekt ist, das den typ darstellt, der formatiert werden soll. Diese Methode gibt das Objekt zurück, das Formatierungsinformationen bereitstellt. .NET unterstützt die folgenden beiden IFormatProvider Implementierungen für die Analyse numerischer Zeichenfolgen:

Im folgenden Beispiel wird versucht, jede Zeichenfolge in einem Array in einen Double Wert zu konvertieren. Zunächst wird versucht, die Zeichenfolge mithilfe eines Formatanbieters zu analysieren, der die Konventionen der englischen Kultur (USA) widerspiegelt. Wenn dieser Vorgang eine FormatExceptionZeichenfolge auslöst, versucht er, die Zeichenfolge mithilfe eines Formatanbieters zu analysieren, der die Konventionen der französischen Kultur (Frankreich) widerspiegelt.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string[] values = { "1,304.16", "$1,456.78", "1,094", "152",
                          "123,45 €", "1 304,16", "Ae9f" };
      double number;
      CultureInfo culture = null;

      foreach (string value in values) {
         try {
            culture = CultureInfo.CreateSpecificCulture("en-US");
            number = Double.Parse(value, culture);
            Console.WriteLine($"{culture.Name}: {value} --> {number}");
         }
         catch (FormatException) {
            Console.WriteLine($"{culture.Name}: Unable to parse '{value}'.");
            culture = CultureInfo.CreateSpecificCulture("fr-FR");
            try {
               number = Double.Parse(value, culture);
               Console.WriteLine($"{culture.Name}: {value} --> {number}");
            }
            catch (FormatException) {
               Console.WriteLine($"{culture.Name}: Unable to parse '{value}'.");
            }
         }
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//    en-US: 1,304.16 --> 1304.16
//
//    en-US: Unable to parse '$1,456.78'.
//    fr-FR: Unable to parse '$1,456.78'.
//
//    en-US: 1,094 --> 1094
//
//    en-US: 152 --> 152
//
//    en-US: Unable to parse '123,45 €'.
//    fr-FR: Unable to parse '123,45 €'.
//
//    en-US: Unable to parse '1 304,16'.
//    fr-FR: 1 304,16 --> 1304.16
//
//    en-US: Unable to parse 'Ae9f'.
//    fr-FR: Unable to parse 'Ae9f'.
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim values() As String = {"1,304.16", "$1,456.78", "1,094", "152",
                                   "123,45 €", "1 304,16", "Ae9f"}
        Dim number As Double
        Dim culture As CultureInfo = Nothing

        For Each value As String In values
            Try
                culture = CultureInfo.CreateSpecificCulture("en-US")
                number = Double.Parse(value, culture)
                Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number)
            Catch e As FormatException
                Console.WriteLine("{0}: Unable to parse '{1}'.",
                                  culture.Name, value)
                culture = CultureInfo.CreateSpecificCulture("fr-FR")
                Try
                    number = Double.Parse(value, culture)
                    Console.WriteLine("{0}: {1} --> {2}", culture.Name, value, number)
                Catch ex As FormatException
                    Console.WriteLine("{0}: Unable to parse '{1}'.",
                                      culture.Name, value)
                End Try
            End Try
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays the following output:
'    en-US: 1,304.16 --> 1304.16
'    
'    en-US: Unable to parse '$1,456.78'.
'    fr-FR: Unable to parse '$1,456.78'.
'    
'    en-US: 1,094 --> 1094
'    
'    en-US: 152 --> 152
'    
'    en-US: Unable to parse '123,45 €'.
'    fr-FR: Unable to parse '123,45 €'.
'    
'    en-US: Unable to parse '1 304,16'.
'    fr-FR: 1 304,16 --> 1304.16
'    
'    en-US: Unable to parse 'Ae9f'.
'    fr-FR: Unable to parse 'Ae9f'.

Analysieren von NumberStyles-Werten

Die Stilelemente (z. B. Leerzeichen, Gruppentrennzeichen und Dezimaltrennzeichen), die beim Parse-Vorgang verarbeitet werden können, werden durch einen NumberStyles Enumerationswert definiert. Standardmäßig werden Zeichenfolgen, die ganzzahlige Werte darstellen, mithilfe des NumberStyles.Integer Werts analysiert, der nur numerische Ziffern, führende und nachfolgende Leerzeichen und ein führendes Zeichen zulässt. Zeichenfolgen, die Gleitkommawerte darstellen, werden unter Verwendung einer Kombination der NumberStyles.Float- und NumberStyles.AllowThousands-Werte analysiert. Dieser zusammengesetzte Stil erlaubt Dezimalstellen zusammen mit führenden und nachfolgenden Leerzeichen, einem Vorzeichen, einem Dezimaltrennzeichen, einem Gruppentrennzeichen und einem Exponenten. Durch Aufrufen einer Überladung der Parse- oder TryParse-Methode, die einen Parameter vom Typ NumberStyles enthalten, und Festlegen eines oder mehrerer NumberStyles-Flags können Sie die Stilelemente steuern, die in der Zeichenfolge vorhanden sein müssen, damit der Analysevorgang erfolgreich ist.

Beispielsweise kann eine Zeichenfolge, die ein Gruppentrennzeichen enthält, nicht mithilfe der Int32 Methode in einen Int32.Parse(String) Wert konvertiert werden. Die Konvertierung ist jedoch erfolgreich, wenn Sie das NumberStyles.AllowThousands Flag verwenden, wie im folgenden Beispiel dargestellt.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string value = "1,304";
      int number;
      IFormatProvider provider = CultureInfo.CreateSpecificCulture("en-US");
      if (Int32.TryParse(value, out number))
         Console.WriteLine($"{value} --> {number}");
      else
         Console.WriteLine($"Unable to convert '{value}'");

      if (Int32.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands,
                        provider, out number))
         Console.WriteLine($"{value} --> {number}");
      else
         Console.WriteLine($"Unable to convert '{value}'");
   }
}
// The example displays the following output:
//       Unable to convert '1,304'
//       1,304 --> 1304
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim value As String = "1,304"
        Dim number As Integer
        Dim provider As IFormatProvider = CultureInfo.CreateSpecificCulture("en-US")
        If Int32.TryParse(value, number) Then
            Console.WriteLine("{0} --> {1}", value, number)
        Else
            Console.WriteLine("Unable to convert '{0}'", value)
        End If

        If Int32.TryParse(value, NumberStyles.Integer Or NumberStyles.AllowThousands,
                          provider, number) Then
            Console.WriteLine("{0} --> {1}", value, number)
        Else
            Console.WriteLine("Unable to convert '{0}'", value)
        End If
    End Sub
End Module
' The example displays the following output:
'       Unable to convert '1,304'
'       1,304 --> 1304

Warnung

Der Analysevorgang verwendet immer die Formatierungskonventionen einer bestimmten Kultur. Wenn Sie keine Kultur angeben, indem Sie ein Objekt für CultureInfo oder NumberFormatInfo übergeben, wird die dem aktuellen Thread zugeordnete Kultur verwendet.

In der folgenden Tabelle sind die Member der NumberStyles Aufzählung aufgeführt und die Auswirkungen auf den Analysevorgang beschrieben.

NumberStyles-Wert Effekt auf die zu analysierende Zeichenkette
NumberStyles.None Es sind nur numerische Ziffern zulässig.
NumberStyles.AllowDecimalPoint Das Dezimaltrennzeichen und die Dezimalstellen sind zulässig. Bei ganzzahligen Werten ist nur Null als Bruchzahl zulässig. Gültige Dezimaltrennzeichen werden von der NumberFormatInfo.NumberDecimalSeparator- oder NumberFormatInfo.CurrencyDecimalSeparator-Eigenschaft bestimmt.
NumberStyles.AllowExponent Das Zeichen "e" oder "E" kann verwendet werden, um exponentielle Notation anzugeben. Weitere Informationen finden Sie unter NumberStyles.
NumberStyles.AllowLeadingWhite Führende Leerzeichen sind zulässig.
NumberStyles.AllowTrailingWhite Nachfolgende Leerzeichen sind zulässig.
NumberStyles.AllowLeadingSign Ein positives oder negatives Vorzeichen kann numerische Ziffern voranstellen.
NumberStyles.AllowTrailingSign Ein positives oder negatives Zeichen kann numerischen Ziffern folgen.
NumberStyles.AllowParentheses Klammern können verwendet werden, um negative Werte anzugeben.
NumberStyles.AllowThousands Das Gruppentrennzeichen ist zulässig. Das Gruppentrennzeichen wird durch die Eigenschaft NumberFormatInfo.NumberGroupSeparator oder die Eigenschaft NumberFormatInfo.CurrencyGroupSeparator bestimmt.
NumberStyles.AllowCurrencySymbol Das Währungssymbol ist zulässig. Das Währungssymbol wird durch die NumberFormatInfo.CurrencySymbol Eigenschaft definiert.
NumberStyles.AllowHexSpecifier Die zu analysierende Zeichenfolge wird als hexadezimale Zahl interpretiert. Sie kann die hexadezimalen Ziffern 0-9, A-F und a-f enthalten. Dieses Flag kann nur zum Analysieren ganzzahliger Werte verwendet werden.
NumberStyles.AllowBinarySpecifier Die zu analysierende Zeichenfolge wird als binäre Zahl interpretiert. Sie kann die Binären Ziffern 0 und 1 enthalten. Dieses Flag kann nur zum Analysieren ganzzahliger Werte verwendet werden.

Darüber hinaus stellt die NumberStyles Enumeration die folgenden zusammengesetzten Stile bereit, die mehrere NumberStyles Flags enthalten.

Zusammengesetzter NumberStyles-Wert Enthält Mitglieder
NumberStyles.Integer Enthält die NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite und NumberStyles.AllowLeadingSign Formatvorlagen. Dies ist die Standardformatvorlage zum Analysieren ganzzahliger Werte.
NumberStyles.Number Enthält die Formatvorlagen NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint und NumberStyles.AllowThousands.
NumberStyles.Float Enthält die NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint und NumberStyles.AllowExponent Formatvorlagen.
NumberStyles.Currency Enthält alle Formatvorlagen außer NumberStyles.AllowExponent und NumberStyles.AllowHexSpecifier.
NumberStyles.Any Enthält alle Formatvorlagen außer NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Enthält die NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite und NumberStyles.AllowHexSpecifier Formatvorlagen.
NumberStyles.BinaryNumber Enthält die NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite und NumberStyles.AllowBinarySpecifier Formatvorlagen.

Analysieren von binären und hexadezimalen BigIntegers

Beim Analysieren der Eingabezeichenfolge mit den Flags AllowHexSpecifier oder AllowBinarySpecifier wird sie als hexadezimale oder binäre Zahl in genau der Länge interpretiert, die die Zeichenfolge besitzt. Die Analyse "11" als binäres BigInteger-Element ergibt -1z. B. die Interpretation des 11 Komplementwerts eines signierten zwei Zeichens mit genau 2 Ziffern. Wenn Sie ein positives Ergebnis erzielen möchten, fügen Sie ein führendes 0 hinzu, wie "011", das als 3 analysiert wird.

Parsen und Unicode-Ziffern

Der Unicode-Standard definiert Codepunkte für Ziffern in verschiedenen Schreibsystemen. Codepunkte von U+0030 bis U+0039 stellen beispielsweise die grundlegenden lateinischen Ziffern 0 bis 9 dar, Codepunkte von U+09E6 bis U+09EF stellen die Bangla-Ziffern 0 bis 9 dar und Codepunkte von U+FF10 bis U+FF19 stellen die Fullwidth-Ziffern 0 bis 9 dar. Die einzigen numerischen Ziffern, die durch Analysemethoden erkannt werden, sind jedoch die grundlegenden lateinischen Ziffern 0-9 mit Codepunkten von U+0030 bis U+0039. Wenn eine numerische Analysemethode eine Zeichenfolge übergeben wird, die andere Ziffern enthält, löst die Methode eine FormatException.

Im folgenden Beispiel wird die Int32.Parse Methode verwendet, um Zeichenfolgen zu analysieren, die aus Ziffern in verschiedenen Schreibsystemen bestehen. Wie die Ausgabe des Beispiels zeigt, ist der Versuch, die grundlegenden lateinischen Ziffern zu analysieren, erfolgreich, aber der Versuch, die Ziffern "Fullwidth", "Arabisch-Indisch" und "Bangla" zu analysieren, schlägt fehl.

using System;

public class Example
{
   public static void Main()
   {
      string value;
      // Define a string of basic Latin digits 1-5.
      value = "\u0031\u0032\u0033\u0034\u0035";
      ParseDigits(value);

      // Define a string of Fullwidth digits 1-5.
      value = "\uFF11\uFF12\uFF13\uFF14\uFF15";
      ParseDigits(value);

      // Define a string of Arabic-Indic digits 1-5.
      value = "\u0661\u0662\u0663\u0664\u0665";
      ParseDigits(value);

      // Define a string of Bangla digits 1-5.
      value = "\u09e7\u09e8\u09e9\u09ea\u09eb";
      ParseDigits(value);
   }

   static void ParseDigits(string value)
   {
      try {
         int number = Int32.Parse(value);
         Console.WriteLine($"'{value}' --> {number}");
      }
      catch (FormatException) {
         Console.WriteLine($"Unable to parse '{value}'.");
      }
   }
}
// The example displays the following output:
//       '12345' --> 12345
//       Unable to parse '12345'.
//       Unable to parse '١٢٣٤٥'.
//       Unable to parse '১২৩৪৫'.
Module Example
    Public Sub Main()
        Dim value As String
        ' Define a string of basic Latin digits 1-5.
        value = ChrW(&h31) + ChrW(&h32) + ChrW(&h33) + ChrW(&h34) + ChrW(&h35)
        ParseDigits(value)

        ' Define a string of Fullwidth digits 1-5.
        value = ChrW(&hff11) + ChrW(&hff12) + ChrW(&hff13) + ChrW(&hff14) + ChrW(&hff15)
        ParseDigits(value)

        ' Define a string of Arabic-Indic digits 1-5.
        value = ChrW(&h661) + ChrW(&h662) + ChrW(&h663) + ChrW(&h664) + ChrW(&h665)
        ParseDigits(value)

        ' Define a string of Bangla digits 1-5.
        value = ChrW(&h09e7) + ChrW(&h09e8) + ChrW(&h09e9) + ChrW(&h09ea) + ChrW(&h09eb)
        ParseDigits(value)
    End Sub

    Sub ParseDigits(value As String)
        Try
            Dim number As Integer = Int32.Parse(value)
            Console.WriteLine("'{0}' --> {1}", value, number)
        Catch e As FormatException
            Console.WriteLine("Unable to parse '{0}'.", value)
        End Try
    End Sub
End Module
' The example displays the following output:
'       '12345' --> 12345
'       Unable to parse '12345'.
'       Unable to parse '١٢٣٤٥'.
'       Unable to parse '১২৩৪৫'.

Siehe auch