Analizowanie ciągów liczbowych na platformie .NET
Wszystkie typy liczbowe mają dwie statyczne metody analizowania i Parse
TryParse
, których można użyć do przekonwertowania reprezentacji ciągu liczby na typ liczbowy. Te metody umożliwiają analizowanie ciągów, które zostały wygenerowane przy użyciu ciągów formatu udokumentowanych w standardowych ciągach formatu liczbowego i niestandardowych ciągów formatu liczbowego. Domyślnie Parse
metody i TryParse
mogą pomyślnie konwertować ciągi zawierające cyfry dziesiętne całkowite tylko na wartości całkowite. Mogą one pomyślnie przekonwertować ciągi zawierające cyfry całkowite i ułamkowe dziesiętne, separatory grup i separator dziesiętny na wartości zmiennoprzecinkowe. Metoda Parse
zgłasza wyjątek, jeśli operacja zakończy się niepowodzeniem, podczas gdy TryParse
metoda zwraca wartość false
.
Uwaga
Począwszy od platformy .NET 7, typy liczbowe na platformie .NET implementują System.IParsable<TSelf> również interfejs, który definiuje IParsable<TSelf>.Parse metody i IParsable<TSelf>.TryParse .
Analizowanie i formatowanie dostawców
Zazwyczaj reprezentacje ciągów wartości liczbowych różnią się kulturą. Elementy ciągów liczbowych, takie jak symbole waluty, separatory grup (lub tysięcy) i separatory dziesiętne, różnią się w zależności od kultury. Analizowanie metod niejawnie lub jawnie używa dostawcy formatu, który rozpoznaje te odmiany specyficzne dla kultury. Jeśli w wywołaniu Parse
metody lub TryParse
nie określono żadnego dostawcy formatu, jest używany dostawca formatu skojarzony z bieżącą NumberFormatInfo.CurrentInfo kulturą (NumberFormatInfoobiekt zwracany przez właściwość).
Dostawca formatu jest reprezentowany przez implementację IFormatProvider . Ten interfejs ma jeden element członkowski, metodę GetFormat , której pojedynczy parametr jest obiektem reprezentującym Type typ do sformatowania. Ta metoda zwraca obiekt, który udostępnia informacje o formatowaniu. Platforma .NET obsługuje następujące dwie IFormatProvider implementacje do analizowania ciągów liczbowych:
CultureInfo Obiekt, którego CultureInfo.GetFormat metoda zwraca NumberFormatInfo obiekt, który zapewnia informacje o formatowaniu specyficznym dla kultury.
NumberFormatInfo Obiekt, którego NumberFormatInfo.GetFormat metoda zwraca się.
Poniższy przykład próbuje przekonwertować każdy ciąg w tablicy na Double wartość. Najpierw próbuje przeanalizować ciąg przy użyciu dostawcy formatu, który odzwierciedla konwencje kultury angielskiej (Stany Zjednoczone). Jeśli ta operacja zgłasza FormatExceptionwyjątek , próbuje przeanalizować ciąg przy użyciu dostawcy formatu, który odzwierciedla konwencje kultury francuskiej (Francji).
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'.
Analiza składniowa i wartości NumberStyles
Elementy stylu (takie jak biały znak, separatory grup i separator dziesiętny), które mogą obsłużyć operacji analizowania, są definiowane przez NumberStyles wartość wyliczenia. Domyślnie ciągi reprezentujące wartości całkowite są analizowane przy użyciu NumberStyles.Integer wartości, która zezwala tylko na cyfry liczbowe, wiodące i końcowe białe znaki oraz znak wiodący. Ciągi reprezentujące wartości zmiennoprzecinkowe są analizowane przy użyciu kombinacji NumberStyles.Float wartości i NumberStyles.AllowThousands . Ten styl złożony zezwala na cyfry dziesiętne wraz z wiodącym i końcowym białym znakiem, znakiem wiodącym, separatorem dziesiętnym, separatorem grupy i wykładnikiem. Wywołując przeciążenie Parse
metody lub TryParse
zawierającej parametr typu NumberStyles i ustawiając co najmniej jedną NumberStyles flagę, można kontrolować elementy stylu, które mogą być obecne w ciągu dla operacji analizy, aby zakończyć się powodzeniem.
Na przykład ciąg zawierający separator grupy nie może zostać przekonwertowany na Int32 wartość przy użyciu Int32.Parse(String) metody . Jednak konwersja powiedzie się, jeśli używasz flagi NumberStyles.AllowThousands , jak pokazano w poniższym przykładzie.
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
Ostrzeżenie
Operacja analizowania zawsze używa konwencji formatowania określonej kultury. Jeśli nie określisz kultury przez przekazanie CultureInfo obiektu lub NumberFormatInfo , zostanie użyta kultura skojarzona z bieżącym wątkiem.
W poniższej tabeli wymieniono elementy członkowskie NumberStyles wyliczenia i opisano wpływ, jaki mają na operację analizowania.
Wartość wyliczenia NumberStyles | Wpływ na ciąg, który ma zostać przeanalizowany |
---|---|
NumberStyles.None | Dozwolone są tylko cyfry liczbowe. |
NumberStyles.AllowDecimalPoint | Dozwolony jest separator dziesiętny i cyfry ułamkowe. W przypadku wartości całkowitych tylko zero jest dozwolone jako cyfra ułamkowa. Prawidłowe separatory dziesiętne są określane przez NumberFormatInfo.NumberDecimalSeparator właściwość or NumberFormatInfo.CurrencyDecimalSeparator . |
NumberStyles.AllowExponent | Znak "e" lub "E" może służyć do wskazywania notacji wykładniczej. Aby uzyskać więcej informacji, zobacz NumberStyles. |
NumberStyles.AllowLeadingWhite | Dozwolone jest wiodące odstępy. |
NumberStyles.AllowTrailingWhite | Dozwolony jest końcowy biały znak. |
NumberStyles.AllowLeadingSign | Znak dodatni lub ujemny może poprzedzać cyfry liczbowe. |
NumberStyles.AllowTrailingSign | Znak dodatni lub ujemny może podążać za cyframi liczbowymi. |
NumberStyles.AllowParentheses | Nawiasy mogą służyć do wskazywania wartości ujemnych. |
NumberStyles.AllowThousands | Separator grupy jest dozwolony. Znak separatora grupy jest określany przez NumberFormatInfo.NumberGroupSeparator właściwość or NumberFormatInfo.CurrencyGroupSeparator . |
NumberStyles.AllowCurrencySymbol | Symbol waluty jest dozwolony. Symbol waluty jest definiowany NumberFormatInfo.CurrencySymbol przez właściwość . |
NumberStyles.AllowHexSpecifier | Ciąg, który ma zostać przeanalizowany, jest interpretowany jako liczba szesnastkowa. Może zawierać cyfry szesnastkowe 0-9, A-F i a-f. Tej flagi można używać tylko do analizowania wartości całkowitych. |
Ponadto NumberStyles wyliczenie zawiera następujące style złożone, które obejmują wiele NumberStyles flag.
Analiza składniowa i cyfry Unicode
Standard Unicode definiuje punkty kodu dla cyfr w różnych systemach pisania. Na przykład punkty kodu od U+0030 do U+0039 reprezentują podstawowe cyfry łacińskie od 0 do 9, punkty kodu od U+09E6 do U+09EF reprezentują cyfry Bangla od 0 do 9, a punkty kodu od U+FF10 do U+FF19 reprezentują cyfry pełne od 0 do 9. Jednak jedyne cyfry liczbowe rozpoznawane przez metody analizowania to podstawowe cyfry łacińskie 0–9 z punktami kodu z U+0030 do U+0039. Jeśli metoda analizowania liczbowego jest przekazywana ciąg zawierający inne cyfry, metoda zgłasza FormatExceptionwartość .
W poniższym przykładzie użyto Int32.Parse metody do analizowania ciągów składających się z cyfr w różnych systemach pisania. Jak pokazano w danych wyjściowych z przykładu, próba przeanalizowanie podstawowych cyfr łacińskich zakończy się powodzeniem, ale próba przeanalizowana cyfr Fullwidth, Arabski-Indic i Bangla kończy się niepowodzeniem.
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 '১২৩৪৫'.