Bagikan melalui


Mengurai string numerik di .NET

Semua jenis numerik memiliki dua metode penguraian statis, Parse dan TryParse, yang dapat Anda gunakan untuk mengonversi representasi string angka menjadi jenis numerik. Metode ini memungkinkan Anda mengurai string yang dihasilkan dengan menggunakan string format yang didokumentasikan dalam String Format Numerik Standar, dan String Format Numerik Kustom. Secara default, metode Parse dan TryParse dapat berhasil mengonversi string yang berisi digit desimal integral hanya ke nilai bilangan bulat. Mereka dapat berhasil mengonversi string yang berisi digit desimal integral dan pecahan, pemisah grup, dan pemisah desimal ke nilai floating-point. Metode Parse melemparkan pengecualian jika operasi gagal, sedangkan metode TryParse mengembalikan false.

Nota

Mulai dari .NET 7, jenis numerik di .NET juga mengimplementasikan antarmuka System.IParsable<TSelf>, yang menentukan metode IParsable<TSelf>.Parse dan IParsable<TSelf>.TryParse.

Memilah dan memformat penyedia

Biasanya, representasi string dari nilai numerik berbeda menurut budaya. Elemen string numerik, seperti simbol mata uang, pemisah kelompok (atau ribuan), dan pemisah desimal, semuanya bervariasi menurut budaya. Metode penguraian baik secara implisit maupun eksplisit menggunakan penyedia format yang mengenali variasi khusus budaya ini. Jika tidak ada penyedia format yang ditentukan dalam panggilan ke metode Parse atau TryParse, penyedia format yang terkait dengan budaya saat ini (objek NumberFormatInfo yang dikembalikan oleh properti NumberFormatInfo.CurrentInfo) digunakan.

Penyedia format diwakili oleh implementasi IFormatProvider. Antarmuka ini memiliki satu anggota, metode GetFormat, yang parameter tunggalnya adalah objek Type yang mewakili jenis yang akan diformat. Metode ini mengembalikan objek yang menyediakan informasi pemformatan. .NET mendukung dua implementasi IFormatProvider berikut untuk mengurai string numerik:

Contoh berikut mencoba mengonversi setiap string dalam array menjadi nilai Double. Pertama-tama mencoba mengurai string dengan menggunakan penyedia format yang mencerminkan konvensi budaya Inggris (Amerika Serikat). Jika operasi ini melemparkan FormatException, operasi ini mencoba mengurai string dengan menggunakan penyedia format yang mencerminkan konvensi budaya Prancis (Prancis).

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'.

Nilai Penguraian dan Gaya Angka

Elemen gaya (seperti spasi putih, pemisah grup, dan pemisah desimal) yang dapat ditangani operasi penguraian ditentukan oleh nilai enumerasi NumberStyles. Secara default, string yang mewakili nilai bilangan bulat diurai dengan menggunakan nilai NumberStyles.Integer, yang hanya mengizinkan digit numerik, spasi putih di depan dan di belakang, dan tanda di depan. Rangkaian karakter yang mewakili nilai floating-point diurai menggunakan kombinasi nilai NumberStyles.Float dan NumberStyles.AllowThousands; gaya gabungan ini memungkinkan digit desimal bersama dengan spasi putih di depan dan belakang, tanda di depan, pemisah desimal, pemisah grup, dan eksponen. Dengan memanggil versi overload dari metode Parse atau TryParse yang menyertakan parameter tipe NumberStyles dan mengatur satu atau beberapa flag NumberStyles, Anda dapat mengontrol elemen gaya yang dapat ada dalam string agar operasi penguraian dapat berhasil.

Misalnya, string yang berisi pemisah grup tidak dapat dikonversi ke nilai Int32 dengan menggunakan metode Int32.Parse(String). Namun, konversi berhasil jika Anda menggunakan bendera NumberStyles.AllowThousands, seperti yang diilustrasikan contoh berikut.

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

Peringatan

Operasi penguraian selalu menggunakan konvensi pemformatan dari budaya tertentu. Jika Anda tidak menentukan pengaturan lokal dengan melewatkan objek CultureInfo atau NumberFormatInfo, pengaturan lokal yang terkait dengan utas saat ini digunakan.

Tabel berikut mencantumkan anggota enumerasi NumberStyles dan menjelaskan efek yang mereka miliki pada operasi penguraian.

Nilai NumberStyles Efek pada string yang akan diurai
NumberStyles.None Hanya digit numerik yang diizinkan.
NumberStyles.AllowDecimalPoint Penggunaan pemisah desimal dan digit pecahan diperbolehkan. Untuk nilai bilangan bulat, hanya nol yang diizinkan sebagai digit pecahan. Pemisah desimal yang valid ditentukan oleh properti NumberFormatInfo.NumberDecimalSeparator atau NumberFormatInfo.CurrencyDecimalSeparator.
NumberStyles.AllowExponent Karakter "e" atau "E" dapat digunakan untuk menunjukkan notasi eksponensial. Untuk informasi selengkapnya, lihat NumberStyles .
NumberStyles.AllowLeadingWhite Spasi kosong di depan diizinkan.
NumberStyles.AllowTrailingWhite Spasi kosong di akhir diperbolehkan.
NumberStyles.AllowLeadingSign Tanda positif atau negatif dapat mendahului digit numerik.
NumberStyles.AllowTrailingSign Tanda positif atau negatif dapat mengikuti digit numerik.
NumberStyles.AllowParentheses Tanda kurung dapat digunakan untuk menunjukkan nilai negatif.
NumberStyles.AllowThousands Pemisah grup diizinkan. Karakter pemisah grup ditentukan oleh properti NumberFormatInfo.NumberGroupSeparator atau NumberFormatInfo.CurrencyGroupSeparator.
NumberStyles.AllowCurrencySymbol Simbol mata uang diizinkan. Simbol mata uang ditentukan oleh properti NumberFormatInfo.CurrencySymbol.
NumberStyles.AllowHexSpecifier String yang akan diurai ditafsirkan sebagai angka heksadesimal. Ini dapat mencakup digit heksadesimal 0-9, A-F, dan a-f. Bendera ini hanya dapat digunakan untuk mengurai nilai bilangan bulat.
NumberStyles.AllowBinarySpecifier String yang akan diurai ditafsirkan sebagai angka biner. Ini dapat mencakup digit biner 0 dan 1. Bendera ini hanya dapat digunakan untuk mengurai nilai bilangan bulat.

Selain itu, enumerasi NumberStyles menyediakan gaya komposit berikut, yang mencakup beberapa bendera NumberStyles.

Nilai Gaya Angka Komposit Menyertakan anggota
NumberStyles.Integer Menyertakan gaya NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, dan NumberStyles.AllowLeadingSign. Ini adalah gaya default yang digunakan untuk mengurai nilai bilangan bulat.
NumberStyles.Number Termasuk gaya NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint, dan NumberStyles.AllowThousands.
NumberStyles.Float Termasuk gaya NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint, dan NumberStyles.AllowExponent.
NumberStyles.Currency Termasuk semua gaya kecuali NumberStyles.AllowExponent dan NumberStyles.AllowHexSpecifier.
NumberStyles.Any Menyertakan semua gaya kecuali NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Menyertakan gaya NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, dan NumberStyles.AllowHexSpecifier.
NumberStyles.BinaryNumber Menyertakan gaya NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, dan NumberStyles.AllowBinarySpecifier.

Mengurai bigInteger biner dan heksadesimal

Saat mengurai BigInteger dengan flag AllowHexSpecifier atau AllowBinarySpecifier, string input ditafsirkan sebagai angka heksadesimal/biner dengan tepat sepanjang string tersebut. Misalnya, parsing "11" sebagai BigInteger biner menghasilkan -1, karena itu adalah interpretasi dari 11 sebagai nilai pelengkap dua bertanda dengan tepat 2 digit. Jika Anda menginginkan hasil positif, tambahkan sebagai awalan 0, seperti "011" yang diurai sebagai 3.

Pemrosesan dan Digit Unicode

Standar Unicode mendefinisikan titik kode untuk digit dalam berbagai sistem penulisan. Misalnya, poin kode dari U+0030 ke U+0039 mewakili digit Latin dasar 0 hingga 9, titik kode dari U+09E6 ke U+09EF mewakili digit Bangla 0 hingga 9, dan titik kode dari U+FF10 ke U+FF19 mewakili digit Fullwidth 0 hingga 9. Namun, satu-satunya digit numerik yang dikenali oleh metode penguraian adalah digit Latin dasar 0-9 dengan titik kode dari U+0030 hingga U+0039. Jika metode penguraian numerik diteruskan string yang berisi digit lain, metode melemparkan FormatException.

Contoh berikut menggunakan metode Int32.Parse untuk mengurai string yang terdiri dari digit dalam sistem penulisan yang berbeda. Seperti yang ditunjukkan oleh output dari contoh, upaya untuk mengurai digit Latin dasar berhasil, tetapi upaya untuk mengurai digit Fullwidth, Arabic-Indic, dan Bangla gagal.

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 '১২৩৪৫'.

Lihat juga