Analýza číselných řetězců v .NET
Všechny číselné typy mají dvě statické metody analýzy a Parse
TryParse
, které 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átových řetězců zdokumentovaný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í Parse
mohou metody TryParse
úspěšně převést řetězce obsahující celočíselné desetinné číslice pouze na celočíselné hodnoty. Mohou úspěšně převést řetězce, které obsahují celočíselné a 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é znázornění čí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. Metody analýzy buď implicitně, nebo explicitně používají poskytovatele formátu, který rozpoznává tyto varianty specifické pro jazykovou verzi. Pokud není v volání metody nebo TryParse
volání Parse
zadán žádný zprostředkovatel formátu, použije se zprostředkovatel formátu přidružený k aktuální jazykové verzi (NumberFormatInfoobjekt vrácený NumberFormatInfo.CurrentInfo vlastností).
Zprostředkovatel formátu je reprezentován implementací IFormatProvider . Toto rozhraní má jeden člen, metodu GetFormat , jejíž jediný 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ů:
Objekt CultureInfo , jehož CultureInfo.GetFormat metoda vrací NumberFormatInfo objekt, který poskytuje informace o formátování specifické pro jazykovou verzi.
Objekt NumberFormatInfo , jehož NumberFormatInfo.GetFormat metoda vrací sám sebe.
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é znaky, oddělovače skupin a oddělovač desetinných míst), které může operace analýzy zpracovat, jsou definovány hodnotou výčtu NumberStyles . 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ími a koncovými prázdnými znaky, počátečním symbolem, oddělovačem desetinných míst, oddělovačem skupin a exponentem. Voláním přetížení Parse
nebo TryParse
metody, která obsahuje parametr typu NumberStyles a nastavením 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, který obsahuje oddělovač skupin, nelze pomocí metody převést na Int32 hodnotu Int32.Parse(String) . Převod však proběhne úspěšně, pokud použijete NumberStyles.AllowThousands příznak, jak je znázorněno v následujícím příkladu.
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
Upozorňující
Operace analýzy vždy používá konvence formátování konkrétní jazykové verze. Pokud nezadáte jazykovou verzi předáním objektu CultureInfo nebo objektu NumberFormatInfo , 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 | Vliv na řetězec, který se má analyzovat |
---|---|
NumberStyles.None | Jsou povoleny pouze číselné číslice. |
NumberStyles.AllowDecimalPoint | Jsou povoleny oddělovače desetinných míst a desetinné číslice. Pro celočíselné hodnoty je povolená pouze nula jako desetinná číslice. Platné oddělovače desetinných míst jsou určeny vlastnostíNumberFormatInfo.NumberDecimalSeparator.NumberFormatInfo.CurrencyDecimalSeparator |
NumberStyles.AllowExponent | Znak "e" nebo "E" lze použít k označení exponenciální notace. Další informace najdete na webu NumberStyles. |
NumberStyles.AllowLeadingWhite | Jsou povoleny úvodní prázdné znaky. |
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 za číselnými číslicemi. |
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 skupin je určen NumberFormatInfo.NumberGroupSeparator vlastností.NumberFormatInfo.CurrencyGroupSeparator |
NumberStyles.AllowCurrencySymbol | Symbol měny je povolen. Symbol měny je definován vlastností NumberFormatInfo.CurrencySymbol . |
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. |
Kromě toho poskytuje NumberStyles výčet následující složené styly, které obsahují více NumberStyles příznaků.
Složená hodnota NumberStyles | Zahrnuje členy. |
---|---|
NumberStyles.Integer | Zahrnuje , NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhitea NumberStyles.AllowLeadingSign styly. Toto je výchozí styl, který se používá k analýze celočíselné hodnoty. |
NumberStyles.Number | Zahrnuje styly NumberStyles.AllowLeadingWhite, , NumberStyles.AllowTrailingWhite, NumberStyles.AllowDecimalPointNumberStyles.AllowLeadingSignNumberStyles.AllowTrailingSigna NumberStyles.AllowThousands styly. |
NumberStyles.Float | Zahrnuje styly NumberStyles.AllowLeadingWhite, , NumberStyles.AllowDecimalPointNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSign, a NumberStyles.AllowExponent styly. |
NumberStyles.Currency | Zahrnuje všechny styly kromě NumberStyles.AllowExponent a NumberStyles.AllowHexSpecifier. |
NumberStyles.Any | Obsahuje všechny styly kromě NumberStyles.AllowHexSpecifier. |
NumberStyles.HexNumber | Zahrnuje , NumberStyles.AllowLeadingWhiteNumberStyles.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 od U+0030 do U+0039 představují základní latinky číslice 0 až 9, body kódu z U+09E6 na U+09EF představují číslice Bangla 0 až 9 a kódové body z U+FF10 až U+FF19 představují číslice Fullwidth 0 až 9. Jedinými číselnými číslicemi rozpoznanými metodami analýzy jsou však základní číslice latinky 0-9 s kódovými body od U+0030 do U+0039. Pokud je číselná metoda analýzy 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 proběhne úspěšně, ale pokus o parsování číslic Fullwidth, Arabic-Indic a 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 '১২৩৪৫'.