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:
Un objeto CultureInfo cuyo método CultureInfo.GetFormat devuelve un objeto NumberFormatInfo que proporciona información de formato específica de la referencia cultural.
Un objeto NumberFormatInfo cuyo método NumberFormatInfo.GetFormat se devuelve a sí mismo.
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
Precaució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 |
---|---|
Solo se permiten dígitos numéricos. |
|
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. |
|
Se puede usar el carácter "e" o "E" para indicar la notación exponencial. Vea NumberStyles para obtener información adicional. |
|
Se permite el espacio en blanco inicial. |
|
Se permite el espacio en blanco final. |
|
Un signo positivo o negativo puede preceder a los dígitos numéricos. |
|
Un signo positivo o negativo puede seguir a los dígitos numéricos. |
|
Se pueden usar paréntesis para indicar valores negativos. |
|
Se permite el separador de grupos. El carácter separador de grupos viene determinado por la propiedad NumberFormatInfo.NumberGroupSeparator o NumberFormatInfo.CurrencyGroupSeparator. |
|
Se permite el símbolo de moneda. El símbolo de moneda está definido por la propiedad NumberFormatInfo.CurrencySymbol. |
|
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 |
---|---|
Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite y NumberStyles.AllowLeadingSign. Este es el estilo predeterminado empleado para analizar valores enteros. |
|
Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowTrailingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowThousands. |
|
Incluye los estilos NumberStyles.AllowLeadingWhite, NumberStyles.AllowTrailingWhite, NumberStyles.AllowLeadingSign, NumberStyles.AllowDecimalPoint y NumberStyles.AllowExponent. |
|
Incluye todos los estilos excepto NumberStyles.AllowExponent y NumberStyles.AllowHexSpecifier. |
|
Incluye todos los estilos excepto NumberStyles.AllowHexSpecifier. |
|
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
Conceptos
Otros recursos
Historial de cambios
Fecha |
Historial |
Motivo |
---|---|---|
Agosto de 2010 |
Se ha revisado exhaustivamente. |
Mejora de la información. |