Dela via


Parsa numeriska strängar i .NET

Alla numeriska typer har två statiska parsningsmetoder och ParseTryParse, som du kan använda för att konvertera strängrepresentationen av ett tal till en numerisk typ. Med de här metoderna kan du parsa strängar som har skapats med hjälp av formatsträngarna som dokumenteras i Standard Numeriska formatsträngar och Anpassade numeriska formatsträngar. Som standard kan metoderna Parse och TryParse framgångsrikt konvertera strängar som endast innehåller decimala siffror till heltalsvärden. De kan konvertera strängar som innehåller heltals- och bråktalstal, gruppavgränsare och en decimalavgränsare till flyttalsvärden. Metoden Parse genererar ett undantag om åtgärden misslyckas, medan TryParse metoden returnerar false.

Anmärkning

Från och med .NET 7 implementerar de numeriska typerna i .NET även gränssnittet System.IParsable<TSelf>, som definierar metoderna IParsable<TSelf>.Parse och IParsable<TSelf>.TryParse.

Parsning och formatleverantörer

Vanligtvis skiljer sig strängrepresentationerna av numeriska värden efter kultur. Element i numeriska strängar, till exempel valutasymboler, gruppavgränsare (eller tusentals) och decimalavgränsare, varierar beroende på kultur. Parsningsmetoder använder antingen implicit eller explicit en formatprovider som identifierar dessa kulturspecifika variationer. Om ingen formatprovider anges i ett anrop till Parse metoden eller TryParse används formatprovidern som är associerad med den aktuella kulturen (objektet NumberFormatInfo som returneras av NumberFormatInfo.CurrentInfo egenskapen).

En formatleverantör representeras av en IFormatProvider-implementering. Det här gränssnittet har en enda medlem, GetFormat metoden, vars enda parameter är ett Type objekt som representerar den typ som ska formateras. Den här metoden returnerar det objekt som innehåller formateringsinformation. .NET stöder följande två IFormatProvider implementeringar för parsning av numeriska strängar:

I följande exempel försöker konvertera varje sträng i en matris till ett Double värde. Den försöker först parsa strängen med hjälp av en formatprovider som återspeglar konventionerna i den engelska kulturen (USA). Om den här åtgärden genererar en FormatExceptionförsöker den parsa strängen med hjälp av en formatprovider som återspeglar konventionerna i den franska kulturen (Frankrike).

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'.

Parsnings- och NumberStyles-värden

Formatelementen (till exempel blanksteg, gruppavgränsare och decimaltecken) som parsningsåtgärden kan hantera definieras av ett NumberStyles uppräkningsvärde. Som standard parsas strängar som representerar heltalsvärden med hjälp av NumberStyles.Integer-värdet, som endast tillåter numeriska siffror, inledande och avslutande blanksteg samt ett inledande tecken, såsom ett plus- eller minustecken. Strängar som representerar flyttalsvärden parsas med hjälp av en kombination av NumberStyles.Float värdena och NumberStyles.AllowThousands . Det här sammansatta formatet tillåter decimaltal tillsammans med inledande och avslutande blanksteg, ett inledande tecken, en decimalavgränsare, en gruppavgränsare och en exponent. Genom att anropa en överlagring av Parse metoden eller TryParse som innehåller en parameter av typen NumberStyles och ange en eller flera NumberStyles flaggor kan du styra de formatelement som kan finnas i strängen för att parsningsåtgärden ska lyckas.

En sträng som innehåller en gruppavgränsare kan till exempel inte konverteras till ett Int32 värde med hjälp Int32.Parse(String) av metoden. Konverteringen lyckas dock om du använder NumberStyles.AllowThousands flaggan, vilket visas i följande exempel.

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

Varning

Parsningsåtgärden använder alltid formateringskonventionerna för en viss kultur. Om du inte anger en kultur genom att skicka ett CultureInfo eller NumberFormatInfo -objekt används kulturen som är associerad med den aktuella tråden.

I följande tabell visas medlemmarna i NumberStyles uppräkningen och den effekt som de har på parsningsåtgärden.

NumberStyles-värde Effekt på strängen som ska analyseras
NumberStyles.None Endast numeriska siffror tillåts.
NumberStyles.AllowDecimalPoint Decimaltecknet och bråktalen tillåts. För heltalsvärden tillåts endast noll som en bråktalssiffra. Giltiga decimalavgränsare bestäms av NumberFormatInfo.NumberDecimalSeparator egenskapen eller NumberFormatInfo.CurrencyDecimalSeparator .
NumberStyles.AllowExponent Tecknet "e" eller "E" kan användas för att ange exponentiell notation. Mer information finns i NumberStyles.
NumberStyles.AllowLeadingWhite Inledande blanksteg tillåts.
NumberStyles.AllowTrailingWhite Avslutande tomt utrymme är tillåtet.
NumberStyles.AllowLeadingSign Ett positivt eller negativt tecken kan föregå numeriska siffror.
NumberStyles.AllowTrailingSign Ett positivt eller negativt tecken kan följa numeriska siffror.
NumberStyles.AllowParentheses Parenteser kan användas för att ange negativa värden.
NumberStyles.AllowThousands Gruppavgränsaren är tillåten. Gruppavgränsartecknet bestäms av NumberFormatInfo.NumberGroupSeparator egenskapen eller NumberFormatInfo.CurrencyGroupSeparator .
NumberStyles.AllowCurrencySymbol Valutasymbolen är tillåten. Valutasymbolen definieras av egenskapen NumberFormatInfo.CurrencySymbol .
NumberStyles.AllowHexSpecifier Strängen som ska parsas tolkas som ett hexadecimalt tal. Den kan innehålla hexadecimala siffror 0-9, A-F och a-f. Den här flaggan kan endast användas för att parsa heltalsvärden.
NumberStyles.AllowBinarySpecifier Strängen som ska parsas tolkas som ett binärt tal. Den kan innehålla de binära siffrorna 0 och 1. Den här flaggan kan endast användas för att parsa heltalsvärden.

Dessutom innehåller NumberStyles-uppräkningen följande kompositstilar, som innefattar flera NumberStyles flaggor.

Sammansatt NumberStyles-värde Inkluderar medlemmar
NumberStyles.Integer Innehåller formatmallarna NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteoch NumberStyles.AllowLeadingSign . Det här är standardformatet som används för att parsa heltalsvärden.
NumberStyles.Number Innehåller formaten NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPointoch NumberStyles.AllowThousands .
NumberStyles.Float Innehåller formatmallarna NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPointoch NumberStyles.AllowExponent .
NumberStyles.Currency Innehåller alla format utom NumberStyles.AllowExponent och NumberStyles.AllowHexSpecifier.
NumberStyles.Any Innehåller alla format utom NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Innehåller formatmallarna NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteoch NumberStyles.AllowHexSpecifier .
NumberStyles.BinaryNumber Innehåller formatmallarna NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteoch NumberStyles.AllowBinarySpecifier .

Parsning av binära och hexadecimala BigIntegers

När du parsar BigInteger med flaggorna AllowHexSpecifier eller AllowBinarySpecifier tolkas indatasträngen som ett hexadecimalt/binärt tal av exakt den längd som strängen har. Till exempel ger parsning "11" som en binär BigInteger -1, eftersom det är tolkningen av 11 som en signerad tvås komplementvärde med exakt 2 siffror. Om du vill ha ett positivt resultat lägger du till en inledande 0, till exempel "011" som parsas som 3.

Parsning och Unicode-siffror

Unicode-standarden definierar kodpunkter för siffror i olika skrivsystem. Kodpunkter från U+0030 till U+0039 representerar till exempel de grundläggande latinska siffrorna 0 till och med 9, kodpunkter från U+09E6 till U+09EF representerar Bangla-siffrorna 0 till 9 och kodpunkterna från U+FF10 till U+FF19 representerar fullwidth-siffrorna 0 till 9. Men de enda numeriska siffrorna som identifieras genom parsningsmetoder är de grundläggande latinska siffrorna 0–9 med kodpunkter från U+0030 till U+0039. Om en numerisk parsningsmetod skickas en sträng som innehåller andra siffror, genererar metoden en FormatException.

I följande exempel används Int32.Parse metoden för att parsa strängar som består av siffror i olika skrivsystem. Som utdata från exemplet visar lyckas försöket att parsa de grundläggande latinska siffrorna, men försöket att parsa siffrorna Fullwidth, Arabic-Indic och Bangla misslyckas.

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 '১২৩৪৫'.

Se även