Parsa numeriska strängar i .NET
Alla numeriska typer har två statiska parsningsmetoder och Parse
TryParse
, som du kan använda för att konvertera strängrepresentationen av ett tal till en numerisk typ. Med de här metoderna kan du parsa strängar som har skapats med hjälp av formatsträngarna som dokumenteras i Standard Numeriska formatsträngar och Anpassade numeriska formatsträngar. Som standard Parse
kan metoderna och TryParse
konvertera strängar som endast innehåller heltalstal till heltalsvärden. De kan konvertera strängar som innehåller heltals- och bråktalstal, gruppavgränsare och en decimalavgränsare till flyttalsvärden. Metoden Parse
genererar ett undantag om åtgärden misslyckas, medan TryParse
metoden returnerar false
.
Kommentar
Från och med .NET 7 implementerar System.IParsable<TSelf> de numeriska typerna i .NET även gränssnittet, som definierar IParsable<TSelf>.Parse metoderna och IParsable<TSelf>.TryParse .
Parsning och formatproviders
Vanligtvis skiljer sig strängrepresentationerna av numeriska värden efter kultur. Element i numeriska strängar, till exempel valutasymboler, gruppavgränsare (eller tusentals) och decimalavgränsare, varierar beroende på kultur. Parsningsmetoder använder antingen implicit eller explicit en formatprovider som identifierar dessa kulturspecifika variationer. Om ingen formatprovider anges i ett anrop till Parse
metoden eller TryParse
används formatprovidern som är associerad med den aktuella kulturen (objektet NumberFormatInfo som returneras av NumberFormatInfo.CurrentInfo egenskapen).
En formatprovider representeras av en IFormatProvider implementering. Det här gränssnittet har en enda medlem, GetFormat metoden, vars enda parameter är ett Type objekt som representerar den typ som ska formateras. Den här metoden returnerar det objekt som innehåller formateringsinformation. .NET stöder följande två IFormatProvider implementeringar för parsning av numeriska strängar:
Ett CultureInfo objekt vars CultureInfo.GetFormat metod returnerar ett NumberFormatInfo objekt som tillhandahåller kulturspecifik formateringsinformation.
Ett NumberFormatInfo objekt vars NumberFormatInfo.GetFormat metod returnerar sig själv.
I följande exempel försöker konvertera varje sträng i en matris till ett Double värde. Den försöker först parsa strängen med hjälp av en formatprovider som återspeglar konventionerna i den engelska kulturen (USA). Om den här åtgärden genererar en FormatExceptionförsöker den parsa strängen med hjälp av en formatprovider som återspeglar konventionerna i den franska kulturen (Frankrike).
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'.
Parsnings- och NumberStyles-värden
Formatelementen (till exempel blanksteg, gruppavgränsare och decimaltecken) som parsningsåtgärden kan hantera definieras av ett NumberStyles uppräkningsvärde. Som standard parsas strängar som representerar heltalsvärden med hjälp NumberStyles.Integer av värdet, som endast tillåter numeriska siffror, inledande och avslutande blanksteg och ett inledande tecken. Strängar som representerar flyttalsvärden parsas med hjälp av en kombination av NumberStyles.Float värdena och NumberStyles.AllowThousands . Det här sammansatta formatet tillåter decimaltal tillsammans med inledande och avslutande blanksteg, ett inledande tecken, en decimalavgränsare, en gruppavgränsare och en exponent. Genom att anropa en överlagring av Parse
metoden eller TryParse
som innehåller en parameter av typen NumberStyles och ange en eller flera NumberStyles flaggor kan du styra de formatelement som kan finnas i strängen för att parsningsåtgärden ska lyckas.
En sträng som innehåller en gruppavgränsare kan till exempel inte konverteras till ett Int32 värde med hjälp Int32.Parse(String) av metoden. Konverteringen lyckas dock om du använder NumberStyles.AllowThousands flaggan, vilket visas i följande exempel.
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
Varning
Parsningsåtgärden använder alltid formateringskonventionerna för en viss kultur. Om du inte anger en kultur genom att skicka ett CultureInfo eller NumberFormatInfo -objekt används kulturen som är associerad med den aktuella tråden.
I följande tabell visas medlemmarna i NumberStyles uppräkningen och den effekt som de har på parsningsåtgärden.
NumberStyles-värde | Effekt på strängen som ska parsas |
---|---|
NumberStyles.None | Endast numeriska siffror tillåts. |
NumberStyles.AllowDecimalPoint | Decimaltecknet och bråktalen tillåts. För heltalsvärden tillåts endast noll som en bråktalssiffra. Giltiga decimalavgränsare bestäms av NumberFormatInfo.NumberDecimalSeparator egenskapen eller NumberFormatInfo.CurrencyDecimalSeparator . |
NumberStyles.AllowExponent | Tecknet "e" eller "E" kan användas för att ange exponentiell notation. Mer information finns i NumberStyles. |
NumberStyles.AllowLeadingWhite | Inledande blanksteg tillåts. |
NumberStyles.AllowTrailingWhite | Avslutande tomt utrymme är tillåtet. |
NumberStyles.AllowLeadingSign | Ett positivt eller negativt tecken kan föregå numeriska siffror. |
NumberStyles.AllowTrailingSign | Ett positivt eller negativt tecken kan följa numeriska siffror. |
NumberStyles.AllowParentheses | Parenteser kan användas för att ange negativa värden. |
NumberStyles.AllowThousands | Gruppavgränsaren är tillåten. Gruppavgränsartecknet bestäms av NumberFormatInfo.NumberGroupSeparator egenskapen eller NumberFormatInfo.CurrencyGroupSeparator . |
NumberStyles.AllowCurrencySymbol | Valutasymbolen är tillåten. Valutasymbolen definieras av egenskapen NumberFormatInfo.CurrencySymbol . |
NumberStyles.AllowHexSpecifier | Strängen som ska parsas tolkas som ett hexadecimalt tal. Den kan innehålla hexadecimala siffror 0-9, A-F och a-f. Den här flaggan kan endast användas för att parsa heltalsvärden. |
Dessutom NumberStyles innehåller uppräkningen följande sammansatta formatmallar, som innehåller flera NumberStyles flaggor.
Parsning och Unicode-siffror
Unicode-standarden definierar kodpunkter för siffror i olika skrivsystem. Kodpunkter från U+0030 till U+0039 representerar till exempel de grundläggande latinska siffrorna 0 till och med 9, kodpunkter från U+09E6 till U+09EF representerar Bangla-siffrorna 0 till 9 och kodpunkterna från U+FF10 till U+FF19 representerar fullwidth-siffrorna 0 till 9. Men de enda numeriska siffrorna som identifieras genom parsningsmetoder är de grundläggande latinska siffrorna 0–9 med kodpunkter från U+0030 till U+0039. Om en numerisk parsningsmetod skickas en sträng som innehåller andra siffror, genererar metoden en FormatException.
I följande exempel används Int32.Parse metoden för att parsa strängar som består av siffror i olika skrivsystem. Som utdata från exemplet visar lyckas försöket att parsa de grundläggande latinska siffrorna, men försöket att parsa siffrorna Fullwidth, Arabic-Indic och Bangla misslyckas.
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 '১২৩৪৫'.