Analyse de chaînes numériques dans .NET
Tous les types numériques disposent de deux méthodes d’analyse statiques, Parse
et TryParse
, que vous pouvez utiliser pour convertir la représentation sous forme de chaîne d’un nombre en type numérique. Ces méthodes vous permettent d’analyser les chaînes qui ont été générées à l’aide de chaînes de format documentées dans Chaînes de format numériques standard et Chaînes de format numériques personnalisées. Par défaut, les méthodes Parse
et TryParse
peuvent convertir correctement les chaînes qui contiennent uniquement des chiffres décimaux intégraux en valeurs entières. Ils peuvent convertir correctement les chaînes qui contiennent des chiffres décimaux intégraux et fractionnaires, des séparateurs de groupe et un séparateur décimal en valeurs à virgule flottante. La méthode Parse
lève une exception si l’opération échoue, tandis que la méthode TryParse
retourne false
.
Notes
À compter de .NET 7, les types numériques dans .NET implémentent également l’interface System.IParsable<TSelf>, qui définit les méthodes IParsable<TSelf>.Parse et IParsable<TSelf>.TryParse.
Analyse et fournisseurs de format
En général, les représentations sous forme de chaîne de valeurs numériques varient selon la culture. Les éléments des chaînes numériques, notamment les symboles monétaires, les séparateurs de groupes (ou de milliers) et les séparateurs décimaux, varient selon la culture. Les méthodes d’analyse utilisent implicitement ou explicitement un fournisseur de format qui identifie ces variantes spécifiques à la culture. Si aucun fournisseur de format n’est spécifié dans un appel à la méthode Parse
ou TryParse
, c’est le fournisseur de format associé à la culture actuelle (l’objet NumberFormatInfo retourné par la propriété NumberFormatInfo.CurrentInfo) qui est utilisé.
Un fournisseur de format est représenté par une implémentation IFormatProvider. Cette interface a un seul membre, la méthode GetFormat, dont l’unique paramètre est un objet Type qui représente le type à mettre en forme. Cette méthode retourne l’objet qui fournit des informations de mise en forme. .NET prend en charge les deux implémentations IFormatProvider suivantes pour analyser les chaînes numériques :
Objet CultureInfo dont la méthode CultureInfo.GetFormat retourne un objet NumberFormatInfo qui fournit des informations de mise en forme propres à la culture.
Objet NumberFormatInfo dont la méthode NumberFormatInfo.GetFormat est retournée.
L’exemple suivant essaie de convertir chaque chaîne d’un tableau en une valeur Double. Il commence par essayer d’analyser la chaîne à l’aide d’un fournisseur de format qui reflète les conventions de la culture anglophone (États-Unis). Si cette opération lève une exception FormatException, il tente d’analyser la chaîne à l’aide d’un fournisseur de format qui reflète les conventions de la culture française (France).
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'.
Analyse et valeurs NumberStyles
Les éléments de style (tels que les espaces blancs, les séparateurs de groupe et le séparateur décimal) que l’opération d’analyse peut gérer sont définis par une valeur d’énumération NumberStyles. Par défaut, les chaînes qui représentent des valeurs entières sont analysées à l’aide de la valeur NumberStyles.Integer, qui autorise uniquement les chiffres numériques, les espaces blancs de début et de fin et un signe de début. Les chaînes qui représentent des valeurs à virgule flottante sont analysées à l’aide d’une combinaison des valeurs NumberStyles.Float et NumberStyles.AllowThousands. Ce style composite autorise les chiffres décimaux avec un espace blanc de début et de fin, un signe de début, un séparateur décimal, un séparateur de groupes et un exposant. Quand vous appelez une surcharge de la méthode Parse
ou TryParse
qui inclut un paramètre de type NumberStyles et que vous définissez un ou plusieurs indicateurs NumberStyles, vous pouvez contrôler les éléments de style pouvant être présents dans la chaîne pour que l’opération d’analyse aboutisse.
Par exemple, une chaîne contenant un séparateur de groupes ne peut pas être convertie en valeur Int32 à l’aide de la méthode Int32.Parse(String). Toutefois, la conversion réussit si vous utilisez l’indicateur NumberStyles.AllowThousands, comme le montre l’exemple suivant.
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
Avertissement
L’opération d’analyse utilise toujours les conventions de mise en forme d’une culture particulière. Si vous ne spécifiez pas de culture en passant un objet CultureInfo ou NumberFormatInfo, la culture associée au thread actuel est utilisée.
Le tableau suivant répertorie les membres de l’énumération NumberStyles et décrit l’effet qu’ils ont sur l’opération d’analyse.
Valeur NumberStyles | Effet sur la chaîne à analyser |
---|---|
NumberStyles.None | Seuls les chiffres sont autorisés. |
NumberStyles.AllowDecimalPoint | Le séparateur décimal et les chiffres fractionnaires sont autorisés. Pour les valeurs entières, le seul chiffre fractionnaire autorisé est zéro. Les séparateurs décimaux valides sont déterminés par la propriété NumberFormatInfo.NumberDecimalSeparator ou NumberFormatInfo.CurrencyDecimalSeparator. |
NumberStyles.AllowExponent | Les caractères « e » ou « E » peuvent être utilisés pour indiquer une notation exponentielle. Pour plus d’informations, consultez NumberStyles. |
NumberStyles.AllowLeadingWhite | L’espace blanc de début est autorisé. |
NumberStyles.AllowTrailingWhite | L’espace blanc de fin est autorisé. |
NumberStyles.AllowLeadingSign | Un signe positif ou négatif peut précéder les chiffres. |
NumberStyles.AllowTrailingSign | Un signe positif ou négatif peut suivre les chiffres. |
NumberStyles.AllowParentheses | Les parenthèses peuvent être utilisées pour indiquer des valeurs négatives. |
NumberStyles.AllowThousands | Le séparateur de groupes est autorisé. Le caractère de séparateur de groupes est déterminé par la propriété NumberFormatInfo.NumberGroupSeparator ou NumberFormatInfo.CurrencyGroupSeparator. |
NumberStyles.AllowCurrencySymbol | Le symbole monétaire est autorisé. Le symbole monétaire est défini par la propriété NumberFormatInfo.CurrencySymbol. |
NumberStyles.AllowHexSpecifier | La chaîne à analyser est interprétée comme un nombre hexadécimal. Elle peut inclure les chiffres hexadécimaux 0-9, A-F et a-f. Cet indicateur peut être utilisé uniquement pour analyser des valeurs entières. |
En outre, l’énumération NumberStyles fournit les styles composites suivants, qui comprennent plusieurs indicateurs NumberStyles.
Analyse et chiffres Unicode
La norme Unicode définit des points de code pour les chiffres dans différents systèmes d’écriture. Par exemple, les points de code U+0030 à U+0039 représentent les chiffres latins de base 0 à 9, les points de code de U+09E6 à U+09EF représentent les chiffres bengalis compris entre 0 et 9, et les points de code U+FF10 à U+FF19 représentent les chiffres pleine chasse compris entre 0 et 9. Toutefois, les seuls chiffres identifiés par les méthodes d’analyse sont les chiffres latins de base 0 à 9 avec des points de code compris entre U+0030 et U+0039. Si une chaîne contenant tout autre chiffre est passée à une méthode d’analyse numérique, celle-ci lève une exception FormatException.
L’exemple suivant utilise la méthode Int32.Parse pour analyser des chaînes composées de chiffres dans différents systèmes d’écriture. Comme l’indique le résultat de l’exemple, la tentative d’analyse des chiffres latins de base réussit, mais la tentative d’analyse des chiffres pleine chasse, arabe-hindi et bengali échoue.
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 '১২৩৪৫'.