Analizar cadenas numéricas en .NETParsing Numeric Strings in NET

Todos los tipos numéricos tienen dos métodos de análisis estáticos, Parse y TryParse, que puede usar para convertir la representación de cadena de un número en un tipo numérico.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. Estos métodos permiten analizar cadenas generadas mediante el uso de las cadenas de formato que se documentan en Cadenas con formato numérico estándar y Cadenas con formato numérico personalizado.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. De forma predeterminada, los métodos Parse y TryParse pueden convertir correctamente las cadenas que contienen dígitos decimales enteros solo en valores enteros.By default, the Parse and TryParse methods can successfully convert strings that contain integral decimal digits only to integer values. Pueden convertir correctamente las cadenas que contienen dígitos decimales enteros y fraccionarios, separadores de grupos y un separador decimal en valores de punto flotante.They can successfully convert strings that contain integral and fractional decimal digits, group separators, and a decimal separator to floating-point values. 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.The Parse method throws an exception if the operation fails, whereas the TryParse method returns false.

Análisis y proveedores de formatoParsing and Format Providers

Normalmente, las representaciones de cadena de valores numéricos se diferencian en la referencia cultural.Typically, the string representations of numeric values differ by culture. Todos los elementos de las cadenas numéricas, como los símbolos de moneda, los separadores de grupo (o millares) y los separadores decimales, varían según la referencia cultural.Elements of numeric strings such as currency symbols, group (or thousands) separators, and decimal separators all vary by culture. 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.Parsing methods either implicitly or explicitly use a format provider that recognizes these culture-specific variations. Si no se especifica ningún proveedor de formato en una llamada al método Parse o TryParse, se usa el proveedor de formato asociado a la referencia cultural del subproceso actual (el objeto NumberFormatInfo devuelto por la propiedad 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.

Un proveedor de formato se representa mediante una implementación IFormatProvider.A format provider is represented by an IFormatProvider implementation. 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.This interface has a single member, the GetFormat method, whose single parameter is a Type object that represents the type to be formatted. Este método devuelve el objeto que proporciona información de formato.This method returns the object that provides formatting information. .NET es compatible con las dos implementaciones IFormatProvider siguientes para analizar cadenas numéricas:.NET supports the following two IFormatProvider implementations for parsing numeric strings:

En el ejemplo siguiente se intenta convertir cada cadena de una matriz en un valor Double.The following example tries to convert each string in an array to a Double value. Primero se intenta analizar la cadena mediante un proveedor de formato que refleja las convenciones de la referencia cultural Inglés (Estados Unidos).It first tries to parse the string by using a format provider that reflects the conventions of the English (United States) culture. Si esta operación produce una excepción FormatException, se intenta analizar la cadena mediante un proveedor de formato que refleja las convenciones de la referencia cultural Francés (Francia).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'.

Análisis y valores NumberStylesParsing and NumberStyles Values

Los elementos de estilo (como espacio en blanco, separadores de grupos y separador decimal) que la operación de análisis puede controlar se definen mediante un valor de enumeración 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. De forma predeterminada, las cadenas que representan valores enteros se analizan mediante el valor NumberStyles.Integer, que solo permite dígitos numéricos, espacio en blanco inicial y final, y un signo inicial.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. Las cadenas que representan valores de punto flotante se analizan mediante una combinación de valores NumberStyles.Float y NumberStyles.AllowThousands. Este estilo compuesto permite dígitos decimales junto con un espacio en blanco inicial y final, un signo inicial, un separador decimal, separador de grupos y un exponente.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. Al llamar a una sobrecarga del método Parse o TryParse que incluya un parámetro de tipo NumberStyles y configurar una o más marcas 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.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.

Por ejemplo, una cadena que contiene un separador de grupos no puede convertirse en un valor Int32 mediante el método 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. Pero la conversión se realiza correctamente si usa la marca NumberStyles.AllowThousands, como se muestra en el ejemplo siguiente.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

Advertencia

La operación de análisis siempre usa las convenciones de formato de una referencia cultural determinada.The parse operation always uses the formatting conventions of a particular culture. Si no pasa un objeto CultureInfo o NumberFormatInfo para especificar una referencia cultural, se usa la referencia cultural asociada al subproceso actual.If you do not specify a culture by passing a CultureInfo or NumberFormatInfo object, the culture associated with the current thread is used.

En la tabla siguiente se enumeran los miembros de la enumeración NumberStyles y se describe el efecto que tienen en la operación de análisis.The following table lists the members of the NumberStyles enumeration and describes the effect that they have on the parsing operation.

Valor NumberStylesNumberStyles value Efecto en la cadena que se va a analizarEffect on the string to be parsed
NumberStyles.None Solo se permiten los dígitos numéricos.Only numeric digits are permitted.
NumberStyles.AllowDecimalPoint Se permiten el separador decimal y los dígitos fraccionarios.The decimal separator and fractional digits are permitted. En el caso de los valores enteros, solo se permite cero como dígito fraccionario.For integer values, only zero is permitted as a fractional digit. La propiedad NumberFormatInfo.NumberDecimalSeparator o NumberFormatInfo.CurrencyDecimalSeparator determina los separadores decimales válidos.Valid decimal separators are determined by the NumberFormatInfo.NumberDecimalSeparator or NumberFormatInfo.CurrencyDecimalSeparator property.
NumberStyles.AllowExponent Se puede usar el carácter "e" o "E" para indicar la notación exponencial.The "e" or "E" character can be used to indicate exponential notation. Vea NumberStyles para obtener información adicional.See NumberStyles for additional information.
NumberStyles.AllowLeadingWhite Se permite el espacio en blanco inicial.Leading white space is permitted.
NumberStyles.AllowTrailingWhite Se permite el espacio en blanco final.Trailing white space is permitted.
NumberStyles.AllowLeadingSign Un signo positivo o negativo puede preceder a los dígitos numéricos.A positive or negative sign can precede numeric digits.
NumberStyles.AllowTrailingSign Un signo positivo o negativo puede seguir a los dígitos numéricos.A positive or negative sign can follow numeric digits.
NumberStyles.AllowParentheses Se pueden usar paréntesis para indicar valores negativos.Parentheses can be used to indicate negative values.
NumberStyles.AllowThousands Se permite el separador de grupos.The group separator is permitted. El carácter de separador de grupo viene determinado por la propiedad NumberFormatInfo.NumberGroupSeparator o NumberFormatInfo.CurrencyGroupSeparator.The group separator character is determined by the NumberFormatInfo.NumberGroupSeparator or NumberFormatInfo.CurrencyGroupSeparator property.
NumberStyles.AllowCurrencySymbol Se permite el símbolo de moneda.The currency symbol is permitted. El símbolo de moneda se define mediante la propiedad NumberFormatInfo.CurrencySymbol.The currency symbol is defined by the NumberFormatInfo.CurrencySymbol property.
NumberStyles.AllowHexSpecifier La cadena que se va a analizar se interpreta como un número hexadecimal.The string to be parsed is interpreted as a hexadecimal number. Puede incluir los dígitos hexadecimales 0-9, A-F y a-f.It can include the hexadecimal digits 0-9, A-F, and a-f. Esta marca solo se puede usar para analizar valores enteros.This flag can be used only to parse integer values.

Además, la enumeración NumberStyles proporciona los siguientes estilos compuestos, que incluyen varias marcas NumberStyles.In addition, the NumberStyles enumeration provides the following composite styles, which include multiple NumberStyles flags.

Valor NumberStyles compuestosComposite NumberStyles value Miembros que incluyeIncludes members
NumberStyles.Integer Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite y NumberStyles.AllowLeadingSign.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowLeadingSign styles. Este es el estilo predeterminado que se usa para analizar valores enteros.This is the default style used to parse integer values.
NumberStyles.Number Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowThousands.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowThousands styles.
NumberStyles.Float Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowExponent.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint, and NumberStyles.AllowExponent styles.
NumberStyles.Currency Incluye todos los estilos excepto NumberStyles.AllowExponent y NumberStyles.AllowHexSpecifier.Includes all styles except NumberStyles.AllowExponent and NumberStyles.AllowHexSpecifier.
NumberStyles.Any Incluye todos los estilos excepto NumberStyles.AllowHexSpecifier.Includes all styles except NumberStyles.AllowHexSpecifier.
NumberStyles.HexNumber Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite y NumberStyles.AllowHexSpecifier.Includes the NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, and NumberStyles.AllowHexSpecifier styles.

Análisis y dígitos UnicodeParsing and Unicode Digits

El estándar Unicode define puntos de código para dígitos de diferentes sistemas de escritura.The Unicode standard defines code points for digits in various writing systems. Por ejemplo, los puntos de código de U+0030 a U+0039 representan los dígitos latinos básicos del 0 al 9, los puntos de código de U+09E6 a U+09EF representan los dígitos de bengalí del 0 al 9, y los puntos de código de U+FF10 a U+FF19 representan los dígitos de ancho completo del 0 al 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. Pero los únicos dígitos numéricos que reconocen los métodos de análisis son los dígitos latinos básicos del 0 al 9 con puntos de código de U+0030 a 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. Si se pasa a un método de análisis numérico una cadena que contenga cualquier otro dígito, el método producirá una excepción FormatException.If a numeric parsing method is passed a string that contains any other digits, the method throws a FormatException.

En el ejemplo siguiente se usa el método Int32.Parse para analizar las cadenas que se componen de dígitos en sistemas de escritura diferentes.The following example uses the Int32.Parse method to parse strings that consist of digits in different writing systems. Como muestra la salida del ejemplo, el intento de analizar los dígitos latinos básicos se realiza correctamente, pero se produce un error en el intento de analizar los dígitos de ancho completo, árabe-hindús y de bengalí.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 '১২৩৪৫'.

Vea tambiénSee also