分析 .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. Parse 方法在操作失败时引发异常,而 TryParse 方法返回 falseThe 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. 但是,分析方法唯一可识别的数字是具有 U+0030 到 U+0039 的码位的基本拉丁文数字 0-9。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