Analýza číselných řetězců v .NET

Všechny číselné typy mají dvě statické metody Parse analýzy, TryParsekteré můžete použít k převodu řetězcové reprezentace čísla na číselný typ. Tyto metody umožňují analyzovat řetězce vytvořené pomocí formátovaných řetězců dokumentovaných v řetězcích standardního číselného formátu a vlastních řetězců číselného formátu. Ve výchozím nastavení mohou metody TryParse úspěšně převést řetězce, Parse které obsahují celočíselné desetinné číslice pouze na celočíselné hodnoty. Mohou úspěšně převést řetězce obsahující integrální a desetinné desetinné číslice, oddělovače skupin a oddělovač desetinných míst na hodnoty s plovoucí desetinnou čárkou. Metoda Parse vyvolá výjimku, pokud operace selže, zatímco TryParse metoda vrátí false.

Poznámka

Počínaje rozhraním .NET 7 implementují System.IParsable<TSelf> také číselné typy v .NET, které definují IParsable<TSelf>.Parse a IParsable<TSelf>.TryParse metody.

Analýza a formátování zprostředkovatelů

Řetězcové reprezentace číselných hodnot se obvykle liší podle jazykové verze. Prvky číselných řetězců, jako jsou symboly měny, oddělovače skupin (nebo tisíců) a oddělovače desetinných míst, se liší podle jazykové verze. Analýza metod implicitně nebo explicitně používá zprostředkovatele formátu, který rozpoznává tyto varianty specifické pro jazykovou verzi. Pokud není v volání Parse nebo TryParse metodě zadán žádný poskytovatel formátu, použije se zprostředkovatel formátu přidružený k aktuální jazykové verzi (NumberFormatInfoobjekt vrácený vlastností).NumberFormatInfo.CurrentInfo

Zprostředkovatel formátu je reprezentován implementací IFormatProvider . Toto rozhraní má jeden člen, metodu GetFormat , jejíž jeden parametr je Type objekt, který představuje typ, který má být formátován. Tato metoda vrátí objekt, který poskytuje informace o formátování. .NET podporuje následující dvě IFormatProvider implementace pro analýzu číselných řetězců:

Následující příklad se pokusí převést každý řetězec v poli na Double hodnotu. Nejprve se pokusí analyzovat řetězec pomocí zprostředkovatele formátu, který odráží konvence jazykové verze angličtiny (USA). Pokud tato operace vyvolá FormatExceptionchybu , pokusí se analyzovat řetězec pomocí zprostředkovatele formátu, který odráží konvence francouzské jazykové verze (Francie).

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

Analýza a hodnoty NumberStyles

Prvky stylu (například prázdné místo, oddělovače skupin a oddělovač desetinných míst), které může operace analýzy zpracovat, jsou definovány NumberStyles hodnotou výčtu. Ve výchozím nastavení se řetězce, které představují celočíselné hodnoty, parsují pomocí NumberStyles.Integer hodnoty, což umožňuje pouze číselné číslice, počáteční a koncové prázdné znaky a počáteční znaménko. Řetězce, které představují hodnoty s plovoucí desetinnou čárkou, se parsují pomocí kombinace NumberStyles.Float hodnot a NumberStyles.AllowThousands hodnot. Tento složený styl umožňuje desetinné číslice spolu s počátečním a koncovým prázdným znakem, počátečním znaménkem, oddělovačem desetinných míst, oddělovačem skupiny a exponentem. Voláním přetížení Parse nebo TryParse metody, která obsahuje parametr typu NumberStyles a nastavení jednoho nebo více NumberStyles příznaků, můžete řídit prvky stylu, které mohou být přítomné v řetězci, aby operace analýzy byla úspěšná.

Například řetězec obsahující oddělovač skupiny nelze pomocí metody převést na Int32 hodnotu Int32.Parse(String) . Převod je však úspěšný, pokud použijete NumberStyles.AllowThousands příznak, jak ukazuje následující příklad.

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

Upozornění

Operace parsování vždy používá konvence formátování konkrétní jazykové verze. Pokud nezadáte jazykovou verzi předáním objektu CultureInfo nebo NumberFormatInfo objektu, použije se jazyková verze přidružená k aktuálnímu vláknu.

Následující tabulka uvádí členy NumberStyles výčtu a popisuje účinek, který mají na operaci analýzy.

Hodnota NumberStyles Účinek na řetězec, který se má analyzovat
NumberStyles.None Jsou povoleny pouze číselné číslice.
NumberStyles.AllowDecimalPoint Oddělovač desetinných míst a desetinné číslice jsou povoleny. Pro celočíselné hodnoty je povolená pouze nula jako desetinná číslice. Platné oddělovače desetinných míst jsou určeny NumberFormatInfo.NumberDecimalSeparator hodnotou nebo NumberFormatInfo.CurrencyDecimalSeparator vlastností.
NumberStyles.AllowExponent Znak "e" nebo "E" lze použít k označení exponenciálního zápisu. Další informace naleznete v tématu NumberStyles.
NumberStyles.AllowLeadingWhite Počáteční prázdné znaky jsou povoleny.
NumberStyles.AllowTrailingWhite Koncové prázdné znaky jsou povolené.
NumberStyles.AllowLeadingSign Kladné nebo záporné znaménko může předcházet číselným číslicům.
NumberStyles.AllowTrailingSign Kladné nebo záporné znaménko může následovat po číselných číslicích.
NumberStyles.AllowParentheses Závorky lze použít k označení záporných hodnot.
NumberStyles.AllowThousands Oddělovač skupin je povolený. Znak oddělovače skupiny je určen vlastnostmi NumberFormatInfo.NumberGroupSeparator nebo NumberFormatInfo.CurrencyGroupSeparator vlastnostmi.
NumberStyles.AllowCurrencySymbol Symbol měny je povolen. Symbol měny je definován NumberFormatInfo.CurrencySymbol vlastností.
NumberStyles.AllowHexSpecifier Řetězec, který se má analyzovat, se interpretuje jako šestnáctkové číslo. Může obsahovat šestnáctkové číslice 0-9, A-F a a-f. Tento příznak lze použít pouze k analýze celočíselné hodnoty.

Výčet navíc NumberStyles poskytuje následující složené styly, které obsahují více NumberStyles příznaků.

Složená hodnota NumberStyles Zahrnuje členy.
NumberStyles.Integer NumberStyles.AllowLeadingWhiteZahrnuje styly , NumberStyles.AllowTrailingWhitea NumberStyles.AllowLeadingSign styly. Toto je výchozí styl použitý k analýze celočíselné hodnoty.
NumberStyles.Number NumberStyles.AllowLeadingWhiteZahrnuje styly , , , NumberStyles.AllowTrailingWhiteNumberStyles.AllowTrailingSignNumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPointa NumberStyles.AllowThousands styly.
NumberStyles.Float NumberStyles.AllowLeadingWhiteZahrnuje styly , , NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSignNumberStyles.AllowDecimalPointa NumberStyles.AllowExponent styly.
NumberStyles.Currency Zahrnuje všechny styly s výjimkou NumberStyles.AllowExponent a NumberStyles.AllowHexSpecifier.
NumberStyles.Any Zahrnuje všechny styly kromě NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber NumberStyles.AllowLeadingWhiteZahrnuje styly , NumberStyles.AllowTrailingWhitea NumberStyles.AllowHexSpecifier styly.

Analýza a číslice v kódování Unicode

Standard Unicode definuje body kódu pro číslice v různých systémech zápisu. Například body kódu z U+0030 na U+0039 představují základní latinky 0 až 9, body kódu z U+09E6 až U+09EF představují číslice Bangla 0 až 9 a kódové body od U+FF10 do U+FF19 představují číslice Fullwidth 0 až 9. Jediné číselné číslice rozpoznané metodami analýzy jsou základní latinky 0–9 s body kódu od U+0030 do U+0039. Pokud je číselná metoda parsování předána řetězec, který obsahuje jakékoli jiné číslice, metoda vyvolá FormatException.

Následující příklad používá metodu Int32.Parse k analýze řetězců, které se skládají z číslic v různých systémech zápisu. Jak ukazuje výstup z příkladu, pokus o parsování základních latinkových číslic je úspěšný, ale pokus o parsování fullwidth, arabštiny a číslic Bangla selže.

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

Viz také