Синтаксический анализ числовых строк в .NET
Все числовые типы имеют два статических метода синтаксического анализа — Parse и TryParse , которые можно использовать для преобразования строкового представления числа в числовой тип. Эти методы позволяют анализировать строки, которые были созданы с помощью строк формата, описанных в разделах Строки стандартных числовых форматов и Строки настраиваемых числовых форматов. По умолчанию методы Parse и TryParse могут успешно преобразовывать строки, содержащие целые десятичные числа, только в целочисленные значения. Они могут успешно преобразовывать строки, содержащие целые и дробные десятичные числа, разделители групп и десятичные разделители, в значения с плавающей запятой. Если операцию выполнить не удалось, метод Parse создает исключение, а метод TryParse возвращает значение false .
Синтаксический анализ и поставщики формата
Как правило, строковые представления числовых значений зависят от языка и региональных параметров. Для различных языков и региональных параметров используются различные элементы численных строк, такие как обозначения денежной единицы, разделители групп (тысяч) и десятичные разделители. Методы анализа неявно или явно используют поставщик формата, распознающий эти различия для разных языков и региональных параметров. Если поставщик формата не задан в вызове метода Parse или TryParse , используется поставщик формата, связанный с текущим языком и региональными параметрами (объект NumberFormatInfo, возвращаемый свойством NumberFormatInfo.CurrentInfo).
Поставщик формата представлен реализацией интерфейса IFormatProvider. Этот интерфейс содержит только один элемент — метод GetFormat, единственным параметром которого является объект Type, представляющий тип для форматирования. Этот метод возвращает объект, предоставляющий сведения о форматировании. .NET поддерживает следующие две реализации IFormatProvider для синтаксического анализа числовых строк:
объект CultureInfo, у которого метод CultureInfo.GetFormat возвращает объект NumberFormatInfo, предоставляющий сведения о форматировании, связанные с языком и региональными параметрами;
объект NumberFormatInfo, у которого метод NumberFormatInfo.GetFormat возвращает сам этот объект.
В следующем примере код пытается преобразовать каждую строку массива в значение Double. Сначала предпринимается попытка выполнить анализ строки с помощью поставщика формата, отражающего правила для языка и региональных параметров "Английский (США)". Если эта операция создает исключение FormatException, предпринимается попытка выполнить синтаксический анализ строки на основе поставщика формата для языка и региональных параметров "Французский (Франция)".
Синтаксический анализ и значения NumberStyles
Распознаваемые при синтаксическом анализе элементы стиля (например, пробелы, разделители групп и десятичные разделители) определяются значением перечисления NumberStyles. По умолчанию строки, представляющие целочисленные значения, анализируются с использованием значения NumberStyles.Integer, которое допускает только цифры, начальные и конечные пробелы и знак в начале. Строки, представляющие значения с плавающей запятой, анализируются с использованием сочетания значений NumberStyles.Float и NumberStyles.AllowThousands. Такой смешанный стиль поддерживает десятичные числа, начальные и конечные пробелы, знак в начале, десятичный разделитель, разделитель групп и показатель степени. Вызвав перегрузку метода Parse или TryParse , содержащего параметр типа NumberStyles, и установив один или несколько флагов NumberStyles, можно управлять выбором элементов стиля, допускаемых в строке для синтаксического анализа.
Например, строка, содержащая разделитель групп, не может быть преобразована в значение Int32 с помощью метода Int32.Parse(String). Однако преобразование пройдет успешно, если установить флаг NumberStyles.AllowThousands, как показано в следующем примере.
Операция синтаксического анализа всегда использует правила форматирования конкретного языка и региональных параметров. Если значения языка и региональных параметров не заданы в объекте CultureInfo или NumberFormatInfo, используются язык и региональные параметры, связанные с текущим потоком.
В следующей таблице приводятся элементы перечисления NumberStyles и описано их влияние на операцию синтаксического анализа.
Значение NumberStyles Влияние на анализируемую строку NumberStyles.None Разрешены только цифры. NumberStyles.AllowDecimalPoint Разрешены десятичный разделитель и дробные числа. Для целых чисел в качестве дробного числа разрешен только ноль. Допустимые десятичные разделители определяются свойством NumberFormatInfo.NumberDecimalSeparator или NumberFormatInfo.CurrencyDecimalSeparator. NumberStyles.AllowExponent Для указания экспоненциального представления может использоваться символ "e" или "E". Дополнительные сведения см. в статье NumberStyles. NumberStyles.AllowLeadingWhite Разрешены начальные пробелы. NumberStyles.AllowTrailingWhite Разрешены конечные пробелы. NumberStyles.AllowLeadingSign Разрешен знак плюс или минус перед числом. NumberStyles.AllowTrailingSign Разрешен знак плюс или минус, следующий за числом. NumberStyles.AllowParentheses Для обозначения отрицательных значений можно использовать скобки. NumberStyles.AllowThousands Разрешен разделитель групп. Символ-разделитель групп определяется свойством NumberFormatInfo.NumberGroupSeparator или NumberFormatInfo.CurrencyGroupSeparator. NumberStyles.AllowCurrencySymbol Разрешено обозначение денежной единицы. Обозначение денежной единицы определяется свойством NumberFormatInfo.CurrencySymbol. NumberStyles.AllowHexSpecifier Анализируемая строка интерпретируется как шестнадцатеричное число. Он может включать символы шестнадцатеричного формата 0–9, A–F или a–f. Этот флаг используется только для анализа целых значений.
Кроме того, перечисление NumberStyles предоставляет следующие смешанные стили, включающие несколько флагов NumberStyles.
Составное значение NumberStyles Включает члены NumberStyles.Integer Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite и NumberStyles.AllowLeadingSign. Это стиль по умолчанию, используемый для анализа целых значений. NumberStyles.Number Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint и NumberStyles.AllowThousands. NumberStyles.Float Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint и NumberStyles.AllowExponent. NumberStyles.Currency Включает все стили, кроме NumberStyles.AllowExponent и NumberStyles.AllowHexSpecifier. NumberStyles.Any Включает все стили, кроме NumberStyles.AllowHexSpecifier. NumberStyles.HexNumber Включает стили NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite и NumberStyles.AllowHexSpecifier.
Синтаксический анализ и цифры в Юникоде
Стандарт Юникод определяет кодовые точки для цифр в различных системах письма. Например, кодовые точки в диапазоне от U+0030 до U+0039 представляют основные цифры от 0 до 9, кодовые точки в диапазоне от U+09E6 до U+09EF представляют бенгальские цифры от 0 до 9, а кодовые точки в диапазоне от U+FF10 до U+FF19 представляют полноширинные цифры от 0 до 9. Однако методами синтаксического анализа распознаются только основные цифры от 0 до 9 (кодовые точки от U+0030 до U+ 0039). Если методу анализа чисел передается строка, содержащая любые другие цифры, метод создает исключение FormatException.
В примере ниже метод Int32.Parse используется для анализа строк, состоящих из цифр различных систем письма. Как показывает вывод, попытка анализа основных цифр завершается успешно, но попытка анализа полноширинных, арабо-индийских и бенгальских цифр заканчивается неудачей.