在 .NET 中剖析數值字串Parsing Numeric Strings in NET

所有數值類型皆有兩個靜態剖析方法:ParseTryParse,可將數字的字串表示轉換成數值類型。All numeric types have two static parsing methods, Parse and TryParse, that you can use to convert the string representation of a number into a numeric type. 這些方法可讓您剖析使用標準數值格式字串自訂數值格式字串中記錄的格式字串所產生的字串。These methods enable you to parse strings that were produced by using the format strings documented in Standard Numeric Format Strings and Custom Numeric Format Strings. 根據預設,ParseTryParse 方法只能將包含十進位數字的字串成功轉換為整數值。By default, the Parse and TryParse methods can successfully convert strings that contain integral decimal digits only to integer values. 它們可以將包含整數和小數的十進位數字、群組分隔符號,以及小數分隔符號的字串,成功轉換為浮點值。They can successfully convert strings that contain integral and fractional decimal digits, group separators, and a decimal separator to floating-point values. 如果作業失敗,即 TryParse 方法傳回 false,則 Parse 方法會擲回例外狀況。The Parse method throws an exception if the operation fails, whereas the TryParse method returns false.

剖析和格式提供者Parsing and Format Providers

數值的字串表示通常會隨文化特性而不同。Typically, the string representations of numeric values differ by culture. 數值字串的元素都會因文化特性而有所不同,包括貨幣符號、群組 (或千分位) 分隔符號以及小數分隔符號。Elements of numeric strings such as currency symbols, group (or thousands) separators, and decimal separators all vary by culture. 剖析方法會隱含或明確使用能夠辨識這些特定文化特性變化的格式提供者。Parsing methods either implicitly or explicitly use a format provider that recognizes these culture-specific variations. 如果 ParseTryParse 方法的呼叫中未指定格式提供者,則會使用與目前執行緒文化特性相關聯的格式提供者 (NumberFormatInfo.CurrentInfo 屬性所傳回的 NumberFormatInfo 物件)。If no format provider is specified in a call to the Parse or TryParse method, the format provider associated with the current thread culture (the NumberFormatInfo object returned by the NumberFormatInfo.CurrentInfo property) is used.

格式提供者會由 IFormatProvider 實作來代表。A format provider is represented by an IFormatProvider implementation. 此介面具有單一成員 (GetFormat 方法),它的單一參數是表示要格式化之類型的 Type 物件。This interface has a single member, the GetFormat method, whose single parameter is a Type object that represents the type to be formatted. 此方法會傳回提供格式設定資訊的物件。This method returns the object that provides formatting information. .NET 支援下列兩個可用來剖析數值字串的 IFormatProvider 實作:.NET supports the following two IFormatProvider implementations for parsing numeric strings:

下列範例會嘗試將陣列中的每個字串轉換為 Double 值。The following example tries to convert each string in an array to a Double value. 它會先嘗試使用反映英文 (美國) 文化特性慣例的格式提供者剖析字串。It first tries to parse the string by using a format provider that reflects the conventions of the English (United States) culture. 如果此作業擲回 FormatException,它就會嘗試使用可反映法文 (法國) 文化特性慣例的格式提供者來剖析字串。If this operation throws a FormatException, it tries to parse the string by using a format provider that reflects the conventions of the French (France) culture.

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

剖析和 NumberStyles 值Parsing and NumberStyles Values

剖析作業可處理的樣式元素 (例如空白字元、群組分隔符號和小數分隔符號),會由 NumberStyles 列舉值來定義。The style elements (such as white space, group separators, and decimal separator) that the parse operation can handle are defined by a NumberStyles enumeration value. 根據預設,代表整數值的字串會使用 NumberStyles.Integer 值進行剖析,這僅允許數字、前置和後置空白字元,以及前置正負號。By default, strings that represent integer values are parsed by using the NumberStyles.Integer value, which permits only numeric digits, leading and trailing white space, and a leading sign. 表示浮點值的字串會使用 NumberStyles.FloatNumberStyles.AllowThousands 值的組合進行剖析,此複合樣式允許十進位數字,以及前置和後置空白字元、前置正負號、小數分隔符號、群組分隔符號和指數。Strings that represent floating-point values are parsed using a combination of the NumberStyles.Float and NumberStyles.AllowThousands values; this composite style permits decimal digits along with leading and trailing white space, a leading sign, a decimal separator, a group separator, and an exponent. 您可以藉由呼叫包含 NumberStyles 類型參數之 ParseTryParse 方法的多載,並設定一或多個 NumberStyles 旗標,來控制可在字串中顯示的樣式元素,使剖析作業得以成功進行。By calling an overload of the Parse or TryParse method that includes a parameter of type NumberStyles and setting one or more NumberStyles flags, you can control the style elements that can be present in the string for the parse operation to succeed.

例如,包含群組分隔符號的字串無法使用 Int32 方法轉換為 Int32.Parse(String) 值。For example, a string that contains a group separator cannot be converted to an Int32 value by using the Int32.Parse(String) method. 然而,如果您使用 NumberStyles.AllowThousands 旗標,則轉換會成功,如下列範例所示。However, the conversion succeeds if you use the NumberStyles.AllowThousands flag, as the following example illustrates.

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

警告

剖析作業一律使用特定文化特性的格式化慣例。The parse operation always uses the formatting conventions of a particular culture. 如果未藉由傳遞 CultureInfoNumberFormatInfo 物件來指定文化特性,就會使用與目前執行緒相關聯的文化特性。If you do not specify a culture by passing a CultureInfo or NumberFormatInfo object, the culture associated with the current thread is used.

下表列出 NumberStyles 列舉的成員,並說明它們對剖析作業的影響。The following table lists the members of the NumberStyles enumeration and describes the effect that they have on the parsing operation.

NumberStyles 值NumberStyles value 對要剖析字串的影響Effect on the string to be parsed
NumberStyles.None 只允許數字。Only numeric digits are permitted.
NumberStyles.AllowDecimalPoint 允許小數分隔符號和小數位。The decimal separator and fractional digits are permitted. 若為整數值,小數位只允許零。For integer values, only zero is permitted as a fractional digit. 有效的小數分隔符號會由 NumberFormatInfo.NumberDecimalSeparatorNumberFormatInfo.CurrencyDecimalSeparator 屬性來決定。Valid decimal separators are determined by the NumberFormatInfo.NumberDecimalSeparator or NumberFormatInfo.CurrencyDecimalSeparator property.
NumberStyles.AllowExponent 可以使用 "e" 或 "E" 字元表示指數標記法。The "e" or "E" character can be used to indicate exponential notation. 如需詳細資訊,請參閱 NumberStylesSee NumberStyles for additional information.
NumberStyles.AllowLeadingWhite 可以使用前置空白字元。Leading white space is permitted.
NumberStyles.AllowTrailingWhite 可以使用後置空白字元。Trailing white space is permitted.
NumberStyles.AllowLeadingSign 數字前面可以使用正負號。A positive or negative sign can precede numeric digits.
NumberStyles.AllowTrailingSign 數字後面可以使用正負號。A positive or negative sign can follow numeric digits.
NumberStyles.AllowParentheses 可以使用括號表示負數值。Parentheses can be used to indicate negative values.
NumberStyles.AllowThousands 允許群組分隔符號。The group separator is permitted. 群組分隔符號字元會由 NumberFormatInfo.NumberGroupSeparatorNumberFormatInfo.CurrencyGroupSeparator 屬性來決定。The group separator character is determined by the NumberFormatInfo.NumberGroupSeparator or NumberFormatInfo.CurrencyGroupSeparator property.
NumberStyles.AllowCurrencySymbol 允許使用貨幣符號。The currency symbol is permitted. 貨幣符號會由 NumberFormatInfo.CurrencySymbol 屬性來定義。The currency symbol is defined by the NumberFormatInfo.CurrencySymbol property.
NumberStyles.AllowHexSpecifier 要剖析的字串會解譯為十六進位數字。The string to be parsed is interpreted as a hexadecimal number. 它可以包含十六進位數字 0-9、A-F 和 a-f。It can include the hexadecimal digits 0-9, A-F, and a-f. 這個旗標只能用於剖析整數值。This flag can be used only to parse integer values.

此外,NumberStyles 列舉提供下列複合樣式,其中包括多個 NumberStyles 旗標。In addition, the NumberStyles enumeration provides the following composite styles, which include multiple NumberStyles flags.

複合的 NumberStyles 值Composite NumberStyles value 包含成員Includes members
NumberStyles.Integer 包含 NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSign 樣式。Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowLeadingSign styles. 這是用來剖析整數值的預設樣式。This is the default style used to parse integer values.
NumberStyles.Number 包含 NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSignNumberStyles.AllowTrailingSignNumberStyles.AllowDecimalPointNumberStyles.AllowThousands 樣式。Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowThousands styles.
NumberStyles.Float 包含 NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowLeadingSignNumberStyles.AllowDecimalPointNumberStyles.AllowExponent 樣式。Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowExponent styles.
NumberStyles.Currency 包含 NumberStyles.AllowExponentNumberStyles.AllowHexSpecifier 以外的所有樣式。Includes all styles except NumberStyles.AllowExponent and NumberStyles.AllowHexSpecifier.
NumberStyles.Any 包含 NumberStyles.AllowHexSpecifier 以外的所有樣式。Includes all styles except NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber 包含 NumberStyles.AllowLeadingWhiteNumberStyles.AllowTrailingWhiteNumberStyles.AllowHexSpecifier 樣式。Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowHexSpecifier styles.

剖析和 Unicode 數字Parsing and Unicode Digits

Unicode 標準會定義各種書寫系統中數字的字碼指標。The Unicode standard defines code points for digits in various writing systems. 例如,U+0030 到 U+0039 的字碼指標表示基本拉丁文數字 0 到 9,U+09E6 到 U+09EF 字碼指標表示孟加拉文數字 0 到 9,而 U+FF10 到 U+FF19 字碼指數表示全形數字 0 到 9。For example, code points from U+0030 to U+0039 represent the basic Latin digits 0 through 9, code points from U+09E6 to U+09EF represent the Bangla digits 0 through 9, and code points from U+FF10 to U+FF19 represent the Fullwidth digits 0 through 9. 不過,剖析方法唯一認識的數字是基本拉丁文數字 0-9 與 U+0030 到 U+0039 字碼指標。However, the only numeric digits recognized by parsing methods are the basic Latin digits 0-9 with code points from U+0030 to U+0039. 如果將包含任何其他數字的字串傳遞給數值剖析方法,則該方法會擲回 FormatExceptionIf a numeric parsing method is passed a string that contains any other digits, the method throws a FormatException.

下列範例會使用 Int32.Parse 方法,來剖析以不同書寫系統的數字組成的字串。The following example uses the Int32.Parse method to parse strings that consist of digits in different writing systems. 如範例的輸出所示,嘗試剖析基本拉丁文數字會成功,而嘗試剖析全型、阿拉伯-印度文和孟加拉文數字則會失敗。As the output from the example shows, the attempt to parse the basic Latin digits succeeds, but the attempt to parse the Fullwidth, Arabic-Indic, and Bangla digits fails.

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

請參閱See also