Partilhar via


Analisando cadeias de caracteres numéricas no .NET

Todos os tipos numéricos têm dois métodos Parse de análise estática e TryParse, que você pode usar para converter a representação de cadeia de caracteres de um número em um tipo numérico. Esses métodos permitem que você analise cadeias de caracteres que foram produzidas usando as cadeias de caracteres de formato documentadas em Cadeias de caracteres de formato numérico padrão e Cadeias de caracteres de formato numérico personalizadas. Por padrão, os Parse métodos e TryParse podem converter com êxito cadeias de caracteres que contêm dígitos decimais integrais apenas em valores inteiros. Eles podem converter com êxito cadeias de caracteres que contêm dígitos decimais integrais e fracionários, separadores de grupo e um separador decimal em valores de vírgula flutuante. O Parse método lança uma exceção se a operação falhar, enquanto o TryParse método retorna false.

Nota

A partir do .NET 7, os tipos numéricos no .NET também implementam a System.IParsable<TSelf> interface, que define os IParsable<TSelf>.Parse métodos e IParsable<TSelf>.TryParse .

Provedores de análise e formato

Normalmente, as representações de cadeia de caracteres de valores numéricos diferem de acordo com a cultura. Os elementos de cadeias de caracteres numéricas, como símbolos de moeda, separadores de grupo (ou milhares) e separadores decimais, variam de acordo com a cultura. Os métodos de análise usam implícita ou explicitamente um provedor de formato que reconhece essas variações específicas da cultura. Se nenhum provedor de formato for especificado em uma chamada para o Parse método ou TryParse , o provedor de formato associado à cultura atual (o NumberFormatInfo objeto retornado pela NumberFormatInfo.CurrentInfo propriedade) será usado.

Um provedor de formato é representado por uma IFormatProvider implementação. Esta interface tem um único membro, o GetFormat método, cujo único parâmetro é um Type objeto que representa o tipo a ser formatado. Esse método retorna o objeto que fornece informações de formatação. O .NET suporta as duas IFormatProvider implementações a seguir para analisar cadeias de caracteres numéricas:

O exemplo a seguir tenta converter cada cadeia de caracteres em uma matriz em um Double valor. Primeiro, ele tenta analisar a cadeia de caracteres usando um provedor de formato que reflete as convenções da cultura inglesa (Estados Unidos). Se essa operação lançar um FormatException, ele tentará analisar a cadeia de caracteres usando um provedor de formato que reflita as convenções da cultura francesa (França).

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

Análise e valores NumberStyles

Os elementos de estilo (como espaço em branco, separadores de grupo e separador decimal) que a operação de análise pode manipular são definidos por um NumberStyles valor de enumeração. Por padrão, as cadeias de caracteres que representam valores inteiros são analisadas usando o NumberStyles.Integer valor, que permite apenas dígitos numéricos, espaço em branco à esquerda e à direita e um sinal à esquerda. As cadeias de caracteres que representam valores de vírgula NumberStyles.Float flutuante são analisadas usando uma combinação dos valores e NumberStyles.AllowThousands , esse estilo composto permite dígitos decimais, juntamente com espaço em branco à esquerda e à direita, um sinal à esquerda, um separador decimal, um separador de grupo e um expoente. Chamando uma sobrecarga do método ou TryParse que inclui um parâmetro do tipo NumberStyles e definindo um ou mais NumberStyles sinalizadores, você pode controlar os elementos de estilo que podem estar presentes na cadeia de Parse caracteres para que a operação de análise seja bem-sucedida.

Por exemplo, uma cadeia de caracteres que contém um separador de grupo não pode ser convertida em um Int32 valor usando o Int32.Parse(String) método. No entanto, a conversão será bem-sucedida se você usar o NumberStyles.AllowThousands sinalizador, como ilustra o exemplo a seguir.

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

Aviso

A operação de análise sempre usa as convenções de formatação de uma cultura específica. Se você não especificar uma cultura passando um CultureInfo ou NumberFormatInfo objeto, a cultura associada ao thread atual será usada.

A tabela a seguir lista os NumberStyles membros da enumeração e descreve o efeito que eles têm na operação de análise.

Valor NumberStyles Efeito na cadeia de caracteres a ser analisada
NumberStyles.None Apenas dígitos numéricos são permitidos.
NumberStyles.AllowDecimalPoint São permitidos o separador decimal e os algarismos fracionários. Para valores inteiros, apenas zero é permitido como um dígito fracionário. Os separadores decimais válidos são determinados pela NumberFormatInfo.NumberDecimalSeparator propriedade or NumberFormatInfo.CurrencyDecimalSeparator .
NumberStyles.AllowExponent O caractere "e" ou "E" pode ser usado para indicar notação exponencial. Para obter mais informações, veja NumberStyles.
NumberStyles.AllowLeadingWhite É permitido espaço em branco à esquerda.
NumberStyles.AllowTrailingWhite É permitido um espaço em branco à direita.
NumberStyles.AllowLeadingSign Um sinal positivo ou negativo pode preceder dígitos numéricos.
NumberStyles.AllowTrailingSign Um sinal positivo ou negativo pode seguir dígitos numéricos.
NumberStyles.AllowParentheses Parênteses podem ser usados para indicar valores negativos.
NumberStyles.AllowThousands O separador de grupo é permitido. O caractere separador de NumberFormatInfo.NumberGroupSeparator grupo é determinado pela propriedade or NumberFormatInfo.CurrencyGroupSeparator .
NumberStyles.AllowCurrencySymbol O símbolo da moeda é permitido. O símbolo da NumberFormatInfo.CurrencySymbol moeda é definido pela propriedade.
NumberStyles.AllowHexSpecifier A cadeia de caracteres a ser analisada é interpretada como um número hexadecimal. Pode incluir os dígitos hexadecimais 0-9, A-F e a-f. Esse sinalizador só pode ser usado para analisar valores inteiros.

Além disso, a NumberStyles enumeração fornece os seguintes estilos compostos, que incluem vários NumberStyles sinalizadores.

Valor NumberStyles composto Inclui membros
NumberStyles.Integer Inclui o NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, e NumberStyles.AllowLeadingSign estilos. Este é o estilo padrão usado para analisar valores inteiros.
NumberStyles.Number Inclui os NumberStyles.AllowLeadingWhiteestilos , NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint, e NumberStyles.AllowThousands .
NumberStyles.Float Inclui os NumberStyles.AllowLeadingWhiteestilos , NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint, e NumberStyles.AllowExponent .
NumberStyles.Currency Inclui todos os estilos, exceto NumberStyles.AllowExponent e NumberStyles.AllowHexSpecifier.
NumberStyles.Any Inclui todos os estilos, exceto NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Inclui o NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, e NumberStyles.AllowHexSpecifier estilos.

Análise e dígitos Unicode

O padrão Unicode define pontos de código para dígitos em vários sistemas de escrita. Por exemplo, os pontos de código de U+0030 a U+0039 representam os dígitos latinos básicos de 0 a 9, os pontos de código de U+09E6 a U+09EF representam os dígitos Bangla de 0 a 9 e os pontos de código de U+FF10 a U+FF19 representam os dígitos de largura total de 0 a 9. No entanto, os únicos dígitos numéricos reconhecidos pelos métodos de análise são os dígitos latinos básicos 0-9 com pontos de código de U+0030 a U+0039. Se um método de análise numérica é passado uma cadeia de caracteres que contém quaisquer outros dígitos, o método lança um FormatExceptionarquivo .

O exemplo a seguir usa o Int32.Parse método para analisar cadeias de caracteres que consistem em dígitos em diferentes sistemas de escrita. Como mostra a saída do exemplo, a tentativa de analisar os dígitos latinos básicos é bem-sucedida, mas a tentativa de analisar os dígitos Fullwidth, Arabic-Indic e Bangla falha.

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

Consulte também