Синтаксический анализ числовых строк в .NETParsing Numeric Strings in NET

Все числовые типы имеют два статических метода синтаксического анализа — Parse и TryParse, которые можно использовать для преобразования строкового представления числа в числовой тип.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. По умолчанию методы Parse и TryParse могут успешно преобразовывать строки, содержащие целые десятичные числа, только в целочисленные значения.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 возвращает значение false.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. Если поставщик формата не задан в вызове метода Parse или TryParse, используется поставщик формата, связанный с текущим языком и региональными параметрами (объект NumberFormatInfo, возвращаемый свойством NumberFormatInfo.CurrentInfo).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'.

Синтаксический анализ и значения NumberStylesParsing 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.Float и NumberStyles.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. Вызвав перегрузку метода Parse или TryParse, содержащего параметр типа NumberStyles, и установив один или несколько флагов 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. Если значения языка и региональных параметров не заданы в объекте CultureInfo или NumberFormatInfo, используются язык и региональные параметры, связанные с текущим потоком.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.

Значение NumberStylesNumberStyles 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.NumberDecimalSeparator или NumberFormatInfo.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. Дополнительные сведения см. в статье NumberStyles.See 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.NumberGroupSeparator или NumberFormatInfo.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.

Составное значение NumberStylesComposite NumberStyles value Включает членыIncludes members
NumberStyles.Integer Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite и NumberStyles.AllowLeadingSign.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowLeadingSign styles. Это стиль по умолчанию, используемый для анализа целых значений.This is the default style used to parse integer values.
NumberStyles.Number Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint и NumberStyles.AllowThousands.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowThousands styles.
NumberStyles.Float Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint и NumberStyles.AllowExponent.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowExponent styles.
NumberStyles.Currency Включает все стили, кроме NumberStyles.AllowExponent и NumberStyles.AllowHexSpecifier.Includes all styles except NumberStyles.AllowExponent and NumberStyles.AllowHexSpecifier.
NumberStyles.Any Включает все стили, кроме NumberStyles.AllowHexSpecifier.Includes all styles except NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite и NumberStyles.AllowHexSpecifier.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowHexSpecifier styles.

Синтаксический анализ и цифры в ЮникодеParsing and Unicode Digits

Стандарт Юникод определяет кодовые точки для цифр в различных системах письма.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. Если методу анализа чисел передается строка, содержащая любые другие цифры, метод создает исключение FormatException.If 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