Megosztás a következőn keresztül:


Numerikus sztringek elemzése a .NET-ben

Minden numerikus típus két statikus elemzési módszerrel rendelkezik, Parse és TryParsea szám sztringképének numerikus típussá alakításához használható. Ezekkel a módszerekkel feldolgozhatja azokat a sztringeket, amelyeket a Standard numerikus formátumsztringek és a Egyéni numerikus formátumsztringek dokumentációjában szereplő formátumláncokkal hoztak létre. Alapértelmezésben a Parse és TryParse metódusok csak a csak számjegyeket tartalmazó sztringeket képesek egész számértékekké konvertálni. Sikeresen konvertálhatják az integrál és tört tizedesjegyeket, csoportelválasztókat és tizedesjeleket tartalmazó sztringeket lebegőpontos értékekké. A Parse metódus kivételt ad, ha a művelet meghiúsul, míg a TryParse metódus ad vissza false.

Megjegyzés:

A .NET 7-től kezdve a .NET numerikus típusai is implementálják az System.IParsable<TSelf> interfészt, amely meghatározza a IParsable<TSelf>.Parse és IParsable<TSelf>.TryParse metódusokat.

Elemzési és formázási szolgáltatók

A numerikus értékek sztring-ábrázolása általában kultúránként eltérő. A numerikus sztringek elemei, például a pénznemszimbólumok, a csoportelválasztók és a tizedeselválasztók kultúránként eltérőek. Az elemzési módszerek implicit módon vagy explicit módon olyan formátumszolgáltatót használnak, amely felismeri ezeket a kultúraspecifikus változatokat. Ha a Parse vagy TryParse metódus hívásában nincs megadva formátumszolgáltató, a rendszer az aktuális kultúrához (a NumberFormatInfo.CurrentInfo objektumot visszaadó NumberFormatInfo tulajdonság alapján) társított formátumszolgáltatót használja.

A formátumszolgáltatót egy IFormatProvider implementáció képviseli. Ennek az interfésznek egyetlen tagja van, a GetFormat metódus, amelynek egyetlen paramétere egy Type olyan objektum, amely a formázandó típust jelöli. Ez a metódus a formázási információkat biztosító objektumot adja vissza. A .NET a következő két IFormatProvider implementációt támogatja numerikus sztringek elemzéséhez:

Az alábbi példa megpróbálja átalakítani a tömbben lévő sztringek mindegyikét egy Double értékké. Egy formátumszolgáltatóval próbálja először elemezni a karakterláncot, amely az angol (Egyesült Államok) kultúra konvencióit tükrözi. Ha ez a művelet kivételt dob egy FormatException miatt, akkor a francia (Franciaország) kultúra konvencióit tükröző formátumszolgáltató segítségével próbálja feldolgozni a karakterláncot.

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

Elemzési és NumberStyles-értékek

Az elemzési művelet által kezelhető stíluselemeket (például a szóközt, a csoportelválasztót és a tizedeselválasztót) enumerálási NumberStyles érték határozza meg. Alapértelmezés szerint az egész számértékeket ábrázoló sztringeket a NumberStyles.Integer érték használatával elemzi a rendszer, amely csak numerikus számjegyeket, elöl és hátul található szóközöket, valamint egy előjelet engedélyez. A lebegőpontos értékeket ábrázoló sztringek az NumberStyles.Float és NumberStyles.AllowThousands értékeket kombinálva vannak elemezve; ez az összetett stílus lehetővé teszi a tizedesjegyek, valamint a kezdő és záró szóközök, az előjel, a tizedeselválasztó, a csoportelválasztó és a kitevő használatát. Az Parse vagy TryParse metódus egy túlterhelésének meghívásával, amely tartalmaz egy NumberStyles típusú paramétert, és egy vagy több NumberStyles jelző beállításával szabályozhatja azokat a stíluselemeket, amelyeknek jelen kell lenniük a sztringben ahhoz, hogy az elemzési művelet sikeres legyen.

Egy csoportelválasztót tartalmazó sztring például nem konvertálható értékké Int32 a Int32.Parse(String) metódus használatával. Az átalakítás azonban sikeres lesz, ha a jelölőt NumberStyles.AllowThousands használja, ahogy az alábbi példa is mutatja.

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

Figyelmeztetés

Az elemzési művelet mindig egy adott kultúra formázási konvencióit használja. Ha nem ad meg egy kultúrát egy CultureInfo vagy NumberFormatInfo objektum átadásával, a rendszer az aktuális szálhoz társított kultúrát használja.

Az alábbi táblázat felsorolja az NumberStyles enumerálás tagjait, és ismerteti az elemzési műveletre gyakorolt hatást.

NumberStyles érték Az elemezni kívánt sztring effektusa
NumberStyles.None Csak numerikus számjegyek engedélyezettek.
NumberStyles.AllowDecimalPoint A tizedesjelek és a törtjegyek megengedettek. Egész számértékek esetén csak a nullát lehet tört számjegyként engedélyezni. Az érvényes tizedesjeleket a NumberFormatInfo.NumberDecimalSeparator vagy a NumberFormatInfo.CurrencyDecimalSeparator tulajdonság határozza meg.
NumberStyles.AllowExponent Az "e" vagy "E" karakter az exponenciális jelölés jelzésére használható. További információért lásd NumberStyles.
NumberStyles.AllowLeadingWhite A vezető szabad terület engedélyezett.
NumberStyles.AllowTrailingWhite A záró fehér szóköz engedélyezett.
NumberStyles.AllowLeadingSign A pozitív vagy negatív jel megelőzheti a numerikus számjegyeket.
NumberStyles.AllowTrailingSign A pozitív vagy negatív jelek numerikus számjegyeket követhetnek.
NumberStyles.AllowParentheses A zárójelek a negatív értékek jelzésére használhatók.
NumberStyles.AllowThousands A csoportelválasztó engedélyezett. A csoportelválasztó karaktert a NumberFormatInfo.NumberGroupSeparator vagy a NumberFormatInfo.CurrencyGroupSeparator tulajdonság határozza meg.
NumberStyles.AllowCurrencySymbol A pénznem szimbóluma engedélyezett. A pénznemszimbólumot a NumberFormatInfo.CurrencySymbol tulajdonság határozza meg.
NumberStyles.AllowHexSpecifier Az elemezni kívánt sztring hexadecimális számként van értelmezve. Tartalmazhat hexadecimális számjegyeket 0-9, A-F és a-f. Ez a jelző csak egész számértékek elemzésére használható.
NumberStyles.AllowBinarySpecifier Az elemezni kívánt sztring bináris számként van értelmezve. Tartalmazhat 0 és 1 bináris számjegyet. Ez a jelző csak egész számértékek elemzésére használható.

Emellett a NumberStyles felsorolási típus a következő összetett stílusokat biztosítja, amelyek több NumberStyles flaget is tartalmaznak.

Kompozit NumberStyles érték Tagokat tartalmaz
NumberStyles.Integer Tartalmazza a NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteés NumberStyles.AllowLeadingSign a stílusokat. Ez az egész számértékek elemzéséhez használt alapértelmezett stílus.
NumberStyles.Number Tartalmazza a NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPointés NumberStyles.AllowThousands stílusokat.
NumberStyles.Float Tartalmazza a NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPointés NumberStyles.AllowExponent stílusokat.
NumberStyles.Currency Az összes stílust tartalmazza, kivéve NumberStyles.AllowExponent és NumberStyles.AllowHexSpecifier.
NumberStyles.Any Az összes stílust tartalmazza a kivételével NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Tartalmazza a NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteés NumberStyles.AllowHexSpecifier a stílusokat.
NumberStyles.BinaryNumber Tartalmazza a NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhiteés NumberStyles.AllowBinarySpecifier a stílusokat.

Bináris és hexadecimális BigIntegers elemzése

BigInteger AllowHexSpecifier vagy AllowBinarySpecifier jelzőkkel a bemeneti sztringet hexadecimális vagy bináris számként értelmezi, amely pontosan olyan hosszú, mint maga a sztring. Például, ha a "11" bináris BigIntegerré van elemezve, az -1-et eredményezi, mivel ez a 11 aláírt, két számjeggyel megadott kettes komplemens értéke. Ha pozitív eredményt szeretne, adjon hozzá egy előtagot 0, például "011", mely így van elemezve 3.

Elemzés és Unicode-számjegyek

A Unicode szabvány kódpontokat határoz meg a különböző írási rendszerekben lévő számjegyekhez. Az U+0030 és az U+0039 közötti kódpontok például a 0 és 9 közötti alap latin számjegyeket, az U+09E6 és az U+09EF közötti kódpontok a Bangla 0-tól 9-ig számjegyeket, az U+FF10-től az U+FF19-ig pedig a 0–9 teljes szélességű számjegyeket jelölik. Azonban az elemzési módszerek csak az alapvető latin számjegyeket ismerik fel, a 0-tól 9-ig terjedőket, amelyek kódpontjai U+0030-tól U+0039-ig terjednek. Ha egy numerikus elemzési metódus olyan sztringet kap, amely bármilyen más számjegyet tartalmaz, a metódus egy FormatException dob.

Az alábbi példa a Int32.Parse metódus használatával elemzi a különböző írásrendszerekben lévő számjegyeket tartalmazó sztringeket. Ahogy a példa kimenete is mutatja, az alapszintű latin számjegyek elemzésére tett kísérlet sikeres, de a Fullwidth, arab-ind és Bangla számjegyek elemzése sikertelen.

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

Lásd még