.NET'te sayısal dizeleri ayrıştırma
Tüm sayısal türlerin, Parse
TryParse
bir sayının dize gösterimini sayısal bir türe dönüştürmek için kullanabileceğiniz iki statik ayrıştırma yöntemi vardır. Bu yöntemler, Standart Sayısal Biçim Dizeleri ve Özel Sayısal Biçim Dizeleri'nde belgelenen biçim dizelerini kullanarak oluşturulan dizeleri ayrıştırmanızı sağlar. Varsayılan olarak, Parse
ve TryParse
yöntemleri tamsayı ondalık basamakları içeren dizeleri yalnızca tamsayı değerlerine başarıyla dönüştürebilir. İntegral ve kesirli ondalık basamaklar, grup ayırıcıları ve ondalık ayırıcı içeren dizeleri kayan nokta değerlerine başarıyla dönüştürebilirler. Parse
yöntemi, işlem başarısız olursa bir özel durum oluştururken TryParse
yöntemi döndürürfalse
.
Not
.NET 7'den başlayarak, .NET'teki sayısal türler ve IParsable<TSelf>.TryParse yöntemlerini tanımlayan IParsable<TSelf>.Parse arabirimi de uygularSystem.IParsable<TSelf>.
Sağlayıcıları ayrıştırma ve biçimlendirme
Genellikle, sayısal değerlerin dize gösterimleri kültüre göre farklılık gösterir. Para birimi simgeleri, grup (veya binler) ayırıcıları ve ondalık ayırıcılar gibi sayısal dizelerin öğelerinin tümü kültüre göre farklılık gösterir. Ayrıştırma yöntemleri örtük olarak veya açıkça bu kültüre özgü varyasyonları tanıyan bir biçim sağlayıcısı kullanır. veya yöntemine Parse
yapılan bir çağrıda biçim sağlayıcısı belirtilmezse, geçerli kültürle ilişkilendirilmiş biçim sağlayıcısı (NumberFormatInfoözellik tarafından NumberFormatInfo.CurrentInfo döndürülen nesne) TryParse
kullanılır.
Biçim sağlayıcısı bir IFormatProvider uygulama tarafından temsil edilir. Bu arabirim, GetFormat tek parametresi biçimlendirilecek türü temsil eden bir nesne olan yöntemi olan tek bir Type üyeye sahiptir. Bu yöntem, biçimlendirme bilgileri sağlayan nesneyi döndürür. .NET, sayısal dizeleri ayrıştırma için aşağıdaki iki IFormatProvider uygulamayı destekler:
CultureInfoCultureInfo.GetFormat Yöntemi kültüre özgü biçimlendirme bilgileri sağlayan bir nesne döndüren nesneNumberFormatInfo.
NumberFormatInfo Yöntemi kendisini döndüren NumberFormatInfo.GetFormat bir nesne.
Aşağıdaki örnek, bir dizideki her dizeyi bir Double değere dönüştürmeye çalışır. İlk olarak İngilizce (Birleşik Devletler) kültürünün kurallarını yansıtan bir biçim sağlayıcısı kullanarak dizeyi ayrıştırmaya çalışır. Bu işlem bir FormatExceptionoluşturursa, Fransızca (Fransa) kültürünün kurallarını yansıtan bir biçim sağlayıcısı kullanarak dizeyi ayrıştırmaya çalışır.
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'.
Ayrıştırma ve NumberStyles Değerleri
Ayrıştırma işleminin işleyebileceği stil öğeleri (boşluk, grup ayırıcıları ve ondalık ayırıcı gibi) bir NumberStyles numaralandırma değeri tarafından tanımlanır. Varsayılan olarak, tamsayı değerlerini temsil eden dizeler, yalnızca sayısal basamaklara, baştaki ve sondaki boşluklara ve baştaki bir işarete izin veren değer kullanılarak NumberStyles.Integer ayrıştırılır. Kayan nokta değerlerini temsil eden dizeler ve NumberStyles.AllowThousands değerlerinin NumberStyles.Float birleşimi kullanılarak ayrıştırılır; bu bileşik stil, baştaki ve sondaki boşluk, baştaki işareti, ondalık ayırıcısı, grup ayırıcısı ve üs ile birlikte ondalık basamaklara izin verir. türünde NumberStyles bir parametre içeren veya TryParse
yönteminin Parse
aşırı yüklemesini çağırarak ve bir veya daha fazla NumberStyles bayrak ayarlayarak, ayrıştırma işleminin başarılı olması için dizede bulunabilecek stil öğelerini denetleyebilirsiniz.
Örneğin, grup ayırıcısı içeren bir dize yöntemi kullanılarak bir Int32 değere Int32.Parse(String) dönüştürülemez. Ancak, aşağıdaki örnekte gösterildiği gibi bayrağını kullanırsanız NumberStyles.AllowThousands dönüştürme başarılı olur.
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
Uyarı
Ayrıştırma işlemi her zaman belirli bir kültürün biçimlendirme kurallarını kullanır. Bir veya NumberFormatInfo nesnesi geçirerek CultureInfo bir kültür belirtmezseniz, geçerli iş parçacığıyla ilişkili kültür kullanılır.
Aşağıdaki tabloda, numaralandırmanın NumberStyles üyeleri listelenir ve ayrıştırma işlemi üzerindeki etkisi açıklanır.
NumberStyles değeri | Ayrıştırılacak dize üzerindeki etkisi |
---|---|
NumberStyles.None | Yalnızca sayısal basamaklara izin verilir. |
NumberStyles.AllowDecimalPoint | Ondalık ayırıcı ve kesirli basamaklara izin verilir. Tamsayı değerleri için kesirli basamak olarak yalnızca sıfıra izin verilir. Geçerli ondalık ayırıcılar veya NumberFormatInfo.CurrencyDecimalSeparator özelliği tarafından NumberFormatInfo.NumberDecimalSeparator belirlenir. |
NumberStyles.AllowExponent | Üstel gösterimi göstermek için "e" veya "E" karakteri kullanılabilir. Daha fazla bilgi için bkz. NumberStyles. |
NumberStyles.AllowLeadingWhite | Öndeki boşluklara izin verilir. |
NumberStyles.AllowTrailingWhite | Sondaki boşluklara izin verilir. |
NumberStyles.AllowLeadingSign | Sayısal basamakların önüne pozitif veya negatif bir işaret gelebilir. |
NumberStyles.AllowTrailingSign | Pozitif veya negatif bir işaret sayısal basamakları izleyebilir. |
NumberStyles.AllowParentheses | Negatif değerleri belirtmek için parantezler kullanılabilir. |
NumberStyles.AllowThousands | Grup ayırıcıya izin verilir. Grup ayırıcı karakteri veya NumberFormatInfo.CurrencyGroupSeparator özelliği tarafından NumberFormatInfo.NumberGroupSeparator belirlenir. |
NumberStyles.AllowCurrencySymbol | Para birimi simgesine izin verilir. Para birimi simgesi özelliği tarafından NumberFormatInfo.CurrencySymbol tanımlanır. |
NumberStyles.AllowHexSpecifier | Ayrıştırılacak dize onaltılık bir sayı olarak yorumlanır. 0-9, A-F ve a-f onaltılık basamakları içerebilir. Bu bayrak yalnızca tamsayı değerlerini ayrıştırmak için kullanılabilir. |
Ayrıca numaralandırma, NumberStyles birden çok NumberStyles bayrak içeren aşağıdaki bileşik stilleri sağlar.
Ayrıştırma ve Unicode Rakamları
Unicode standardı, çeşitli yazma sistemlerindeki basamaklar için kod noktalarını tanımlar. Örneğin, U+0030'dan U+0039'a kadar olan kod noktaları 0 ile 9 arasındaki temel Latin basamaklarını, U+09E6'dan U+09EF'ye kadar olan kod noktaları 0 ile 9 arasındaki Bangla basamaklarını ve U+FF10'dan U+FF19'a kadar olan kod noktaları 0 ile 9 arasındaki Tam Tuş basamaklarını temsil eder. Ancak, ayrıştırma yöntemleri tarafından tanınan tek sayısal basamaklar, U+0030 ile U+0039 arası kod noktaları içeren temel Latin basamakları 0-9'dur. Sayısal ayrıştırma yöntemine başka basamaklar içeren bir dize geçirilirse, yöntemi bir FormatExceptionoluşturur.
Aşağıdaki örnek, farklı yazma sistemlerindeki basamaklardan oluşan dizeleri ayrıştırmak için yöntemini kullanır Int32.Parse . Örnekte gösterildiği gibi, temel Latin basamaklarını ayrıştırma girişimi başarılı olur, ancak Fullwidth, Arapça-Hint ve Bangla basamaklarını ayrıştırma girişimi başarısız olur.
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 '১২৩৪৫'.