Analizowanie ciągów liczbowych na platformie .NET
Wszystkie typy liczbowe mają dwie statyczne metody analizowania, Parse
i 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 utworzone za pomocą ciągów formatu opisanych w standardowych formatach liczbowych oraz niestandardowych formatach liczbowych. Domyślnie metody Parse
i TryParse
mogą pomyślnie konwertować ciągi zawierające cyfry całkowite tylko na wartości całkowite. Mogą pomyślnie przekonwertować ciągi, które zawierają cyfry dziesiętne całkowite i ułamkowe, separatory grup oraz separator dziesiętny na wartości zmiennoprzecinkowe. Metoda Parse
zgłasza wyjątek, jeśli operacja nie powiedzie się, podczas gdy metoda TryParse
zwraca false
.
Uwaga
Począwszy od platformy .NET 7, typy liczbowe na platformie .NET implementują również interfejs System.IParsable<TSelf>, który definiuje metody IParsable<TSelf>.Parse i IParsable<TSelf>.TryParse.
Dostawcy analizowania i formatowania
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. Metody analizy korzystają niejawnie lub jawnie z dostawcy formatu, który rozpoznaje zmiany charakterystyczne dla danej kultury. Jeśli żaden dostawca formatu nie jest określony w wywołaniu metody Parse
lub TryParse
, jest używany dostawca formatu skojarzony z bieżącą kulturą (obiekt NumberFormatInfo zwrócony przez właściwość NumberFormatInfo.CurrentInfo).
Dostawca formatu jest reprezentowany przez implementację IFormatProvider. Ten interfejs ma jeden element członkowski, metodę GetFormat, której pojedynczy parametr jest obiektem Type reprezentującym typ do sformatowania. Ta metoda zwraca obiekt, który udostępnia informacje o formatowaniu. Platforma .NET obsługuje następujące dwie implementacje IFormatProvider do analizowania ciągów liczbowych:
Obiekt CultureInfo, którego metoda CultureInfo.GetFormat zwraca obiekt NumberFormatInfo, który zapewnia informacje o formatowaniu specyficznym dla kultury.
Obiekt NumberFormatInfo, którego metoda NumberFormatInfo.GetFormat zwraca go.
Poniższy przykład próbuje przekonwertować każdy ciąg w tablicy na wartość Double. Najpierw próbuje przeanalizować ciąg przy użyciu dostawcy formatu, który odzwierciedla konwencje kultury angielskiej (Stanów Zjednoczonych). Jeśli ta operacja generuje FormatException, próbuje przeanalizować ciąg przy użyciu dostawcy formatu, który odzwierciedla konwencje kultury francuskiej.
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'.
Analizowanie i wartości stylów liczbnych
Elementy stylu (takie jak biały znak, separatory grup i separator dziesiętny), które operacja analizowania może obsłużyć, są definiowane przez wartość wyliczenia NumberStyles. Domyślnie ciągi reprezentujące wartości całkowite są analizowane przy użyciu wartości NumberStyles.Integer, 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 wartości NumberStyles.Float 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 metody Parse
lub TryParse
, które zawiera parametr typu NumberStyles i ustawiając co najmniej jedną flagę NumberStyles, można kontrolować elementy stylu, które muszą być obecne w ciągu, aby operacja analizy się powiodła.
Na przykład nie można przekonwertować ciągu zawierającego separator grupy na wartość Int32 przy użyciu metody Int32.Parse(String). 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($"{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
Ostrzeżenie
Operacja analizowania zawsze używa konwencji formatowania określonej kultury. Jeśli nie określisz kultury, przekazując obiekt CultureInfo lub NumberFormatInfo, używana jest kultura skojarzona z bieżącym wątkiem.
W poniższej tabeli wymieniono elementy członkowskie wyliczenia NumberStyles i opisano wpływ, jaki mają na operację analizowania.
Wartość 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 właściwość NumberFormatInfo.NumberDecimalSeparator lub 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 dopuszczalny. Znak separatora grupy jest określany przez właściwość NumberFormatInfo.NumberGroupSeparator lub NumberFormatInfo.CurrencyGroupSeparator. |
NumberStyles.AllowCurrencySymbol | Symbol waluty jest dozwolony. Symbol waluty jest definiowany przez właściwość NumberFormatInfo.CurrencySymbol. |
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 wyliczenie NumberStyles zawiera następujące style złożone, które obejmują wiele flag NumberStyles.
Wartość złożona NumberStyles | Obejmuje członków |
---|---|
NumberStyles.Integer | Zawiera style NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhitei NumberStyles.AllowLeadingSign. Jest to domyślny styl używany do analizowania wartości całkowitych. |
NumberStyles.Number | Zawiera style NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPointi NumberStyles.AllowThousands. |
NumberStyles.Float | Zawiera style NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPointi NumberStyles.AllowExponent. |
NumberStyles.Currency | Obejmuje wszystkie style z wyjątkiem NumberStyles.AllowExponent i NumberStyles.AllowHexSpecifier. |
NumberStyles.Any | Zawiera wszystkie style z wyjątkiem NumberStyles.AllowHexSpecifier. |
NumberStyles.HexNumber | Zawiera style NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhitei NumberStyles.AllowHexSpecifier. |
Analizowanie 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 FormatException.
W poniższym przykładzie użyto metody Int32.Parse 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 przeanalizowania podstawowych cyfr łacińskich zakończyła się powodzeniem, ale próba przeanalizowania cyfr jednobajtowych, arabsko-indyjskich i bengalskich zakończyła 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($"'{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 '১২৩৪৫'.
Zobacz też
- NumberStyles
- analizowanie ciągów
- Typy formatowania