Delen via


Numerieke tekenreeksen parseren in .NET

Alle numerieke typen hebben twee statische parseringsmethoden Parse en TryParse, die u kunt gebruiken om de tekenreeksweergave van een getal te converteren naar een numeriek type. Met deze methoden kunt u tekenreeksen parseren die zijn geproduceerd met behulp van de notatietekenreeksen die zijn gedocumenteerd in tekenreeksen met standaard numerieke notatie en tekenreeksen met aangepaste numerieke notatie. Standaard kunnen de Parse en TryParse methoden tekenreeksen die integrale decimalen bevatten, alleen converteren naar gehele getallen. Ze kunnen tekenreeksen die integrale en fractionele decimale cijfers bevatten, scheidingstekens voor groepen en een decimaalteken converteren naar drijvende-kommawaarden. De Parse methode genereert een uitzondering als de bewerking mislukt, terwijl de TryParse methode retourneert false.

Notitie

Vanaf .NET 7 implementeren de numerieke typen in .NET ook de System.IParsable<TSelf> interface, waarmee de IParsable<TSelf>.Parse en IParsable<TSelf>.TryParse methoden worden gedefinieerd.

Providers parseren en opmaken

Normaal gesproken verschillen de tekenreeksweergaven van numerieke waarden per cultuur. Elementen van numerieke tekenreeksen, zoals valutasymbolen, scheidingstekens voor groepen (of duizenden) en scheidingstekens voor decimalen, variëren allemaal per cultuur. Bij het parseren van methoden wordt impliciet of expliciet gebruikgemaakt van een indelingsprovider die deze cultuurspecifieke variaties herkent. Als er geen indelingsprovider is opgegeven in een aanroep naar de Parse of TryParse methode, wordt de indelingsprovider die is gekoppeld aan de huidige cultuur (het NumberFormatInfo object dat door de NumberFormatInfo.CurrentInfo eigenschap wordt geretourneerd) gebruikt.

Een indelingsprovider wordt vertegenwoordigd door een IFormatProvider implementatie. Deze interface heeft één lid, de GetFormat methode, waarvan één parameter een Type object is dat het type vertegenwoordigt dat moet worden opgemaakt. Met deze methode wordt het object geretourneerd dat opmaakinformatie biedt. .NET ondersteunt de volgende twee IFormatProvider implementaties voor het parseren van numerieke tekenreeksen:

In het volgende voorbeeld wordt geprobeerd om elke tekenreeks in een matrix te converteren naar een Double waarde. Eerst wordt geprobeerd de tekenreeks te parseren met behulp van een indelingsprovider die de conventies van de Engelse cultuur (Verenigde Staten) weerspiegelt. Als deze bewerking een FormatExceptionbewerking genereert, probeert deze de tekenreeks te parseren met behulp van een indelingsprovider die de conventies van de Franse cultuur (Frankrijk) weerspiegelt.

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("{0}: {1} --> {2}", culture.Name, value, number);
         }
         catch (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 (FormatException) {
               Console.WriteLine("{0}: Unable to parse '{1}'.",
                                 culture.Name, 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'.

Waarden voor parseren en numberstyles

De stijlelementen (zoals witruimte, groepsscheidingstekens en decimaalteken) die door de parseringsbewerking kunnen worden verwerkt, worden gedefinieerd door een NumberStyles opsommingswaarde. Tekenreeksen die gehele getallen vertegenwoordigen, worden standaard geparseerd met behulp van de NumberStyles.Integer waarde, waardoor alleen numerieke cijfers, voorloop- en volgspaties en een voorloopteken worden toegestaan. Tekenreeksen die drijvende-kommawaarden vertegenwoordigen, worden geparseerd met behulp van een combinatie van de NumberStyles.Float waarden en NumberStyles.AllowThousands waarden. Met deze samengestelde stijl worden decimale cijfers samen met voorloop- en volgspaties, een voorloopteken, een decimaalteken, een scheidingsteken voor groepen en een exponent toegestaan. Door een overbelasting aan te roepen van de Parse of TryParse methode die een parameter van het type NumberStyles bevat en een of meer NumberStyles vlaggen in te stellen, kunt u de stijlelementen bepalen die aanwezig kunnen zijn in de tekenreeks om de parseringsbewerking te laten slagen.

Een tekenreeks die een groepsscheidingsteken bevat, kan bijvoorbeeld niet worden geconverteerd naar een Int32 waarde met behulp van de Int32.Parse(String) methode. De conversie slaagt echter als u de NumberStyles.AllowThousands vlag gebruikt, zoals in het volgende voorbeeld wordt geïllustreerd.

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("{0} --> {1}", value, number);
      else
         Console.WriteLine("Unable to convert '{0}'", value);

      if (Int32.TryParse(value, NumberStyles.Integer | NumberStyles.AllowThousands,
                        provider, out number))
         Console.WriteLine("{0} --> {1}", value, number);
      else
         Console.WriteLine("Unable to convert '{0}'", 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

Waarschuwing

De parseringsbewerking maakt altijd gebruik van de opmaakconventies van een bepaalde cultuur. Als u geen cultuur opgeeft door een CultureInfo of NumberFormatInfo object door te geven, wordt de cultuur gebruikt die aan de huidige thread is gekoppeld.

De volgende tabel bevat de leden van de NumberStyles opsomming en beschrijft het effect dat ze hebben op de parseringsbewerking.

Getalstijlwaarde Effect op de tekenreeks die moet worden geparseerd
NumberStyles.None Alleen numerieke cijfers zijn toegestaan.
NumberStyles.AllowDecimalPoint Het decimaalteken en de breuktekens zijn toegestaan. Voor gehele getallen is alleen nul toegestaan als een breukcijfer. Geldige decimaaltekens worden bepaald door de NumberFormatInfo.NumberDecimalSeparator of NumberFormatInfo.CurrencyDecimalSeparator eigenschap.
NumberStyles.AllowExponent Het teken 'e' of 'E' kan worden gebruikt om exponentiële notatie aan te geven. Zie NumberStyles voor meer informatie.
NumberStyles.AllowLeadingWhite Voorloopspaties zijn toegestaan.
NumberStyles.AllowTrailingWhite Volgspaties zijn toegestaan.
NumberStyles.AllowLeadingSign Een positief of negatief teken kan voorafgaan aan numerieke cijfers.
NumberStyles.AllowTrailingSign Een positief of negatief teken kan numerieke cijfers volgen.
NumberStyles.AllowParentheses Haakjes kunnen worden gebruikt om negatieve waarden aan te geven.
NumberStyles.AllowThousands Het groepsscheidingsteken is toegestaan. Het groepsscheidingsteken wordt bepaald door de NumberFormatInfo.NumberGroupSeparator of NumberFormatInfo.CurrencyGroupSeparator eigenschap.
NumberStyles.AllowCurrencySymbol Het valutasymbool is toegestaan. Het valutasymbool wordt gedefinieerd door de NumberFormatInfo.CurrencySymbol eigenschap.
NumberStyles.AllowHexSpecifier De tekenreeks die moet worden geparseerd, wordt geïnterpreteerd als een hexadecimaal getal. Het kan de hexadecimale cijfers 0-9, A-F en a-f bevatten. Deze vlag kan alleen worden gebruikt om gehele getallen te parseren.

Daarnaast biedt de NumberStyles opsomming de volgende samengestelde stijlen, waaronder meerdere NumberStyles vlaggen.

Samengestelde getalstijlwaarde Inclusief leden
NumberStyles.Integer Bevat de NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteen NumberStyles.AllowLeadingSign stijlen. Dit is de standaardstijl die wordt gebruikt om gehele getallen te parseren.
NumberStyles.Number Bevat de NumberStyles.AllowLeadingWhitestijlen , , NumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSignen NumberStyles.AllowDecimalPointNumberStyles.AllowThousands stijlen.
NumberStyles.Float Bevat de NumberStyles.AllowLeadingWhitestijlen , NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSignen NumberStyles.AllowDecimalPointNumberStyles.AllowExponent stijlen.
NumberStyles.Currency Bevat alle stijlen behalve NumberStyles.AllowExponent en NumberStyles.AllowHexSpecifier.
NumberStyles.Any Bevat alle stijlen behalve NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Bevat de NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteen NumberStyles.AllowHexSpecifier stijlen.

Parseren en Unicode-cijfers

De Unicode-standaard definieert codepunten voor cijfers in verschillende schrijfsystemen. Codepunten van U+0030 tot U+0039 vertegenwoordigen bijvoorbeeld de latijnse basiscijfer 0 tot en met 9, codepunten van U+09E6 tot U+09EF vertegenwoordigen de Bangla-cijfers 0 tot en met 9 en codepunten van U+FF10 tot U+FF19 vertegenwoordigen de fullwidth digits 0 tot en met 9. De enige numerieke cijfers die door parseringsmethoden worden herkend, zijn echter de latijnse basiscijfers 0-9 met codepunten van U+0030 tot U+0039. Als een numerieke parseringsmethode wordt doorgegeven aan een tekenreeks die andere cijfers bevat, genereert de methode een FormatException.

In het volgende voorbeeld wordt de Int32.Parse methode gebruikt om tekenreeksen te parseren die bestaan uit cijfers in verschillende schrijfsystemen. Zoals de uitvoer uit het voorbeeld laat zien, slaagt de poging om de latijnse basiscijfers te parseren, maar de poging om de Volledigewidth-, Arabisch-Indic- en Bangla-cijfers te parseren mislukt.

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("'{0}' --> {1}", value, number);
      }
      catch (FormatException) {
         Console.WriteLine("Unable to parse '{0}'.", 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 '১২৩৪৫'.

Zie ook