Compartir a través de


Analizar cadenas numéricas

Todos los tipos numéricos tienen dos métodos estáticos de análisis, Parse y TryParse, que puede usar para convertir la representación de cadena de un número en un tipo numérico. Estos métodos permiten analizar cadenas que se generaron mediante las cadenas de formato documentadas en Cadenas con formato numérico estándar y Cadenas con formato numérico personalizado. De forma predeterminada, los métodos Parse y TryParse pueden convertir correctamente cadenas que contienen dígitos decimales enteros únicamente a valores enteros. Pueden convertir correctamente cadenas que contienen dígitos decimales enteros y fraccionarios, separadores de grupo y un separador decimal en valores de punto flotante. El método Parse produce una excepción si se produce un error en la operación, mientras que el método TryParse devuelve false.

Análisis y proveedores de formato

Normalmente, las representaciones de cadena de los valores numéricos difieren según la referencia cultural. Los elementos de cadenas numéricas como símbolos de moneda, separadores de grupo (o miles), separadores decimales y símbolos de moneda varían según la referencia cultural. Los métodos de análisis usan implícita o explícitamente un proveedor de formato que reconoce estas variaciones específicas de la referencia cultural. Si no se especifica ningún proveedor de formato en una llamada al método Parse o TryParse, se usará el proveedor de formato asociado a la referencia cultural del subproceso actual (el objeto NumberFormatInfo devuelto por la propiedad NumberFormatInfo.CurrentInfo).

Un proveedor de formato se representa mediante una implementación de IFormatProvider. Esta interfaz tiene un solo miembro, el método GetFormat, cuyo único parámetro es un objeto Type que representa el tipo al que se va a dar formato. Este método devuelve el objeto que proporciona información de formato. .NET Framework admite las dos implementaciones siguientes de IFormatProvider para analizar cadenas numéricas:

En el ejemplo siguiente se intenta convertir cada cadena de una matriz a un valor de tipo Double. Primero se intenta analizar la cadena usando un proveedor de formato que refleje las convenciones de la referencia cultural Inglés (Estados Unidos). Si esta operación produce FormatException, se intenta analizar la cadena usando un proveedor de formato que refleje las convenciones de la referencia cultural Francés (Francia).

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

Análisis y valores NumberStyles

Los elementos de estilo (como espacio en blanco, separadores de grupos y separador decimal) que la operación de análisis puede tratar están definidos por un valor de la enumeración NumberStyles. De forma predeterminada, las cadenas que representan valores enteros se analizan usando el valor de NumberStyles.Integer, que solo permite dígitos numéricos, espacio en blanco inicial y final, y un signo inicial. Las cadenas que representan valores de punto flotante se analizan mediante una combinación de los valores de NumberStyles.Float y NumberStyles.AllowThousands; este estilo compuesto permite dígitos decimales junto con espacios en blanco iniciales y finales, un signo inicial, un separador decimal, un separador de grupos y un exponente. Llamando a una sobrecarga del método Parse o TryParse que incluye un parámetro de tipo NumberStyles y estableciendo una o más marcas de NumberStyles, puede controlar los elementos de estilo que pueden estar presentes en la cadena para que la operación de análisis se realice correctamente.

Por ejemplo, una cadena que contiene un separador de grupos no se puede convertir en un valor de tipo Int32 usando el método Int32.Parse(String). Sin embargo, la conversión se realiza correctamente si usa la marca NumberStyles.AllowThousands, como se muestra en el ejemplo siguiente.

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
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
Nota de precauciónPrecaución

La operación de análisis usa siempre las convenciones de formato de una referencia cultural determinada.Si no especifica una referencia cultural pasando un objeto CultureInfo o NumberFormatInfo, se usará la referencia cultural asociada al subproceso actual.

En la tabla siguiente se muestran los miembros de la enumeración NumberStyles y se describe el efecto que tienen sobre la operación de análisis.

Valor de NumberStyles

Efecto sobre la cadena que se va a analizar

NumberStyles.None

Solo se permiten dígitos numéricos.

NumberStyles.AllowDecimalPoint

Se permiten el separador decimal y dígitos fraccionarios. Para los valores enteros, solo se permite cero como dígito fraccionario. Los separadores decimales válidos se determinan mediante la propiedad NumberFormatInfo.NumberDecimalSeparator o NumberFormatInfo.CurrencyDecimalSeparator.

NumberStyles.AllowExponent

Se puede usar el carácter "e" o "E" para indicar la notación exponencial. Vea NumberStyles para obtener información adicional.

NumberStyles.AllowLeadingWhite

Se permite el espacio en blanco inicial.

NumberStyles.AllowTrailingWhite

Se permite el espacio en blanco final.

NumberStyles.AllowLeadingSign

Un signo positivo o negativo puede preceder a los dígitos numéricos.

NumberStyles.AllowTrailingSign

Un signo positivo o negativo puede seguir a los dígitos numéricos.

NumberStyles.AllowParentheses

Se pueden usar paréntesis para indicar valores negativos.

NumberStyles.AllowThousands

Se permite el separador de grupos. El carácter separador de grupos viene determinado por la propiedad NumberFormatInfo.NumberGroupSeparator o NumberFormatInfo.CurrencyGroupSeparator.

NumberStyles.AllowCurrencySymbol

Se permite el símbolo de moneda. El símbolo de moneda está definido por la propiedad NumberFormatInfo.CurrencySymbol.

NumberStyles.AllowHexSpecifier

La cadena que se va a analizar se interpreta como un número hexadecimal. Puede incluir los dígitos hexadecimales 0-9, A-F y a-f. Esta marca solo se puede usar para analizar valores enteros.

Además, la enumeración NumberStyles proporciona los estilos compuestos siguientes, que incluyen varias marcas de NumberStyles.

Valor compuesto de NumberStyles

Incluye miembros

NumberStyles.Integer

Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite y NumberStyles.AllowLeadingSign. Este es el estilo predeterminado empleado para analizar valores enteros.

NumberStyles.Number

Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowThousands.

NumberStyles.Float

Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowExponent.

NumberStyles.Currency

Incluye todos los estilos excepto NumberStyles.AllowExponent y NumberStyles.AllowHexSpecifier.

NumberStyles.Any

Incluye todos los estilos excepto NumberStyles.AllowHexSpecifier.

NumberStyles.HexNumber

Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite y NumberStyles.AllowHexSpecifier.

Análisis y dígitos Unicode

El estándar Unicode define puntos de código para los dígitos en diversos sistemas de escritura. Por ejemplo, los puntos de código de U+0030 a U+0039 representan los dígitos latinos básicos 0 a 9, los puntos de código de U+09E6 a U+09EF representan los dígitos de bengalí 0 a 9 y los puntos de código de U+FF10 a U+FF19 representan los dígitos de ancho completo 0 a 9. Sin embargo, los únicos dígitos numéricos reconocidos por los métodos de análisis son los dígitos latinos básicos 0-9 con los puntos de código de U+0030 a U+0039. Si a un método de análisis numérico se le pasa una cadena que contiene cualquier otro dígito, el método produce una excepción FormatException.

En el ejemplo siguiente se usa el método Int32.Parse para analizar cadenas que constan de dígitos en diferentes sistemas de escritura. Como muestra el resultado del ejemplo, el intento de analizar los dígitos latinos básicos se ejecuta correctamente, pero el intento de analizar los dígitos de ancho completo, árabo-índico y bengalí producirá un error.

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

Vea también

Referencia

NumberStyles

Conceptos

Aplicar formato a tipos

Otros recursos

Analizar cadenas

Historial de cambios

Fecha

Historial

Motivo

Agosto de 2010

Se ha revisado exhaustivamente.

Mejora de la información.