Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Vous comparez des chaînes pour répondre à l’une des deux questions suivantes : « Ces deux chaînes sont-elles égales ? » ou « Dans quel ordre ces chaînes doivent-elles être placées dans le tri ? »
Les facteurs suivants compliquent ces deux questions :
- Vous pouvez choisir une comparaison ordinale ou linguistique.
- Vous pouvez choisir si les majuscules et les minuscules sont importantes.
- Vous pouvez choisir des comparaisons spécifiques à la culture.
- Les comparaisons linguistiques sont dépendantes de la culture et de la plateforme.
Les System.StringComparison champs d’énumération représentent ces choix :
- CurrentCulture : comparez les chaînes à l’aide de règles de tri sensibles à la culture et de la culture actuelle.
- CurrentCultureIgnoreCase : comparez les chaînes à l’aide de règles de tri respectant la culture, la culture actuelle et ignorez le cas des chaînes comparées.
- InvariantCulture : comparez les chaînes à l’aide de règles de tri sensibles à la culture et de la culture invariante.
- InvariantCultureIgnoreCase : comparez les chaînes à l’aide de règles de tri respectant la culture, la culture invariante et ignorez le cas des chaînes comparées.
- Ordinal : comparez les chaînes à l’aide de règles de tri ordinales (binaires).
- OrdinalIgnoreCase : comparez les chaînes à l’aide de règles de tri ordinales (binaires) et ignorez le cas des chaînes comparées.
Lorsque vous comparez des chaînes, vous définissez un ordre entre eux. Les comparaisons sont utilisées pour trier une séquence de chaînes. Une fois la séquence dans un ordre connu, il est plus facile de rechercher, à la fois pour les logiciels et pour les humains. D’autres comparaisons peuvent vérifier si les chaînes sont identiques. Ces vérifications de la sameness sont similaires à l’égalité, mais certaines différences, telles que les différences de cas, peuvent être ignorées.
Comparaisons ordinales par défaut
Par défaut, les opérations les plus courantes :
- String.Equals
-
String.Equality et String.Inequality, autrement dit, les opérateurs
==d’égalité et!=, effectuent respectivement une comparaison ordinale sensible à la casse. String.Equals a une surcharge où un StringComparison argument peut être fourni pour modifier ses règles de tri. L’exemple suivant illustre ce qui suit :
string root = @"C:\users";
string root2 = @"C:\Users";
bool result = root.Equals(root2);
Console.WriteLine($"Ordinal comparison: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");
result = root.Equals(root2, StringComparison.Ordinal);
Console.WriteLine($"Ordinal comparison: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");
Console.WriteLine($"Using == says that <{root}> and <{root2}> are {(root == root2 ? "equal" : "not equal")}");
La comparaison ordinale par défaut ne prend pas en compte les règles linguistiques lors de la comparaison de chaînes. Il compare la valeur binaire de chaque Char objet dans deux chaînes. Par conséquent, la comparaison ordinale par défaut respecte également la casse.
Le test d'égalité avec String.Equals et les opérateurs == et != diffère de la comparaison de chaînes effectuée à l'aide des méthodes String.CompareTo et Compare(String, String). Ils effectuent toutes une comparaison sensible à la casse. Toutefois, alors que les tests d’égalité effectuent une comparaison ordinale, les méthodes CompareTo et Compare effectuent une comparaison linguistique sensibilisée à la culture à l’aide de la culture actuelle. Rendez claire l’intention du code en appelant une fonction surchargée qui spécifie explicitement le type de comparaison à réaliser.
Vous pouvez utiliser l’opérateur is et un modèle constant comme alternative à == lorsque l’opérande droit est une constante.
Comparaisons ordinales ne respectant pas la casse
La méthode String.Equals(String, StringComparison) vous permet de spécifier une valeur StringComparison de StringComparison.OrdinalIgnoreCase pour une comparaison ordinale insensible à la casse. Il existe également une méthode statique String.Compare(String, String, StringComparison) qui effectue une comparaison ordinale en ignorant la casse si vous spécifiez une valeur de StringComparison.OrdinalIgnoreCase pour l’argument StringComparison. Ces comparaisons sont affichées dans le code suivant :
string root = @"C:\users";
string root2 = @"C:\Users";
bool result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
bool areEqual = String.Equals(root, root2, StringComparison.OrdinalIgnoreCase);
int comparison = String.Compare(root, root2, comparisonType: StringComparison.OrdinalIgnoreCase);
Console.WriteLine($"Ordinal ignore case: <{root}> and <{root2}> are {(result ? "equal." : "not equal.")}");
Console.WriteLine($"Ordinal static ignore case: <{root}> and <{root2}> are {(areEqual ? "equal." : "not equal.")}");
if (comparison < 0)
{
Console.WriteLine($"<{root}> is less than <{root2}>");
}
else if (comparison > 0)
{
Console.WriteLine($"<{root}> is greater than <{root2}>");
}
else
{
Console.WriteLine($"<{root}> and <{root2}> are equivalent in order");
}
Ces méthodes utilisent les conventions de casse de la culture invariante pour effectuer une comparaison ordinale insensible à la casse.
Comparaisons linguistiques
De nombreuses méthodes de comparaison de chaînes (par exemple String.StartsWith) utilisent des règles linguistiques pour la culture actuelle par défaut pour classer leurs entrées. Cette comparaison linguistique est parfois appelée « ordre de tri des mots ». Lorsque vous effectuez une comparaison linguistique, certains caractères Unicode nonphanumériques peuvent avoir des poids spéciaux attribués. Par exemple, le trait d’union « - » peut avoir un petit poids lui étant attribué afin que «co-op» et « coop » apparaissent en regard des uns des autres dans l’ordre de tri. Certains caractères de contrôle non imprimables peuvent être ignorés. En outre, certains caractères Unicode peuvent être équivalents à une séquence d’instances Char . L’exemple suivant utilise l’expression « Ils dansent dans la rue ». en allemand avec « ss » (U+0073 U+0073) dans une chaîne et « ß » (U+00DF) dans une autre. Linguistiquement (dans Windows), « ss » est équivalent au caractère allemand « ß », pour les cultures "en-US" et "de-DE".
string first = "Sie tanzen auf der Straße.";
string second = "Sie tanzen auf der Strasse.";
Console.WriteLine($"First sentence is <{first}>");
Console.WriteLine($"Second sentence is <{second}>");
bool equal = String.Equals(first, second, StringComparison.InvariantCulture);
Console.WriteLine($"The two strings {(equal == true ? "are" : "are not")} equal.");
showComparison(first, second);
string word = "coop";
string words = "co-op";
string other = "cop";
showComparison(word, words);
showComparison(word, other);
showComparison(words, other);
void showComparison(string one, string two)
{
int compareLinguistic = String.Compare(one, two, StringComparison.InvariantCulture);
int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal);
if (compareLinguistic < 0)
{
Console.WriteLine($"<{one}> is less than <{two}> using invariant culture");
}
else if (compareLinguistic > 0)
{
Console.WriteLine($"<{one}> is greater than <{two}> using invariant culture");
}
else
{
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using invariant culture");
}
if (compareOrdinal < 0)
{
Console.WriteLine($"<{one}> is less than <{two}> using ordinal comparison");
}
else if (compareOrdinal > 0)
{
Console.WriteLine($"<{one}> is greater than <{two}> using ordinal comparison");
}
else
{
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using ordinal comparison");
}
}
Sur Windows, avant .NET 5, l’ordre de tri « cop », « coop » et «co-op» change lorsque vous passez d’une comparaison linguistique à une comparaison ordinale. Les deux phrases allemandes sont également comparées différemment à l’aide des différents types de comparaison. Avant .NET 5, les API de globalisation .NET utilisaient des bibliothèques NLS (National Language Support). Dans .NET 5 et versions ultérieures, les API de globalisation .NET utilisent des bibliothèques International Components for Unicode (ICU) qui unifient le comportement de globalisation de .NET sur tous les systèmes d’exploitation pris en charge.
Comparaisons à l’aide de cultures spécifiques
L’exemple suivant stocke des CultureInfo objets pour les cultures en-US et de-DE. Les comparaisons sont effectuées à l’aide d’un CultureInfo objet pour garantir une comparaison propre à la culture. La culture utilisée affecte les comparaisons linguistiques. L’exemple suivant montre les résultats de la comparaison des deux phrases allemandes à l’aide de la culture «en-US» et de la culture «de-DE» :
string first = "Sie tanzen auf der Straße.";
string second = "Sie tanzen auf der Strasse.";
Console.WriteLine($"First sentence is <{first}>");
Console.WriteLine($"Second sentence is <{second}>");
var en = new System.Globalization.CultureInfo("en-US");
// For culture-sensitive comparisons, use the String.Compare
// overload that takes a StringComparison value.
int i = String.Compare(first, second, en, System.Globalization.CompareOptions.None);
Console.WriteLine($"Comparing in {en.Name} returns {i}.");
var de = new System.Globalization.CultureInfo("de-DE");
i = String.Compare(first, second, de, System.Globalization.CompareOptions.None);
Console.WriteLine($"Comparing in {de.Name} returns {i}.");
bool b = String.Equals(first, second, StringComparison.CurrentCulture);
Console.WriteLine($"The two strings {(b ? "are" : "are not")} equal.");
string word = "coop";
string words = "co-op";
string other = "cop";
showComparison(word, words, en);
showComparison(word, other, en);
showComparison(words, other, en);
void showComparison(string one, string two, System.Globalization.CultureInfo culture)
{
int compareLinguistic = String.Compare(one, two, en, System.Globalization.CompareOptions.None);
int compareOrdinal = String.Compare(one, two, StringComparison.Ordinal);
if (compareLinguistic < 0)
{
Console.WriteLine($"<{one}> is less than <{two}> using en-US culture");
}
else if (compareLinguistic > 0)
{
Console.WriteLine($"<{one}> is greater than <{two}> using en-US culture");
}
else
{
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using en-US culture");
}
if (compareOrdinal < 0)
{
Console.WriteLine($"<{one}> is less than <{two}> using ordinal comparison");
}
else if (compareOrdinal > 0)
{
Console.WriteLine($"<{one}> is greater than <{two}> using ordinal comparison");
}
else
{
Console.WriteLine($"<{one}> and <{two}> are equivalent in order using ordinal comparison");
}
}
Les comparaisons sensibles à la culture sont généralement utilisées pour comparer et trier des chaînes de caractères saisies par les utilisateurs avec d'autres chaînes de caractères saisies par des utilisateurs. Les caractères et conventions de tri de ces chaînes peuvent varier en fonction des paramètres régionaux de l’ordinateur de l’utilisateur. Même les chaînes qui contiennent des caractères identiques peuvent trier différemment selon la culture du thread actuel.
Tri linguistique et recherche de chaînes dans des tableaux
Les exemples suivants montrent comment trier et rechercher des chaînes dans un tableau à l’aide d’une comparaison linguistique dépendante de la culture actuelle. Vous utilisez les méthodes statiques Array qui prennent un System.StringComparer paramètre.
L’exemple suivant montre comment trier un tableau de chaînes de caractères à l’aide de la culture actuelle :
string[] lines =
[
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
];
Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}
Console.WriteLine("\n\rSorted order:");
// Specify Ordinal to demonstrate the different behavior.
Array.Sort(lines, StringComparer.CurrentCulture);
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}
Une fois le tableau trié, vous pouvez rechercher des entrées à l’aide d’une recherche binaire. Une recherche binaire commence au milieu de la collection pour déterminer la moitié de la collection qui contiendrait la chaîne recherchée. Chaque comparaison suivante subdivise la partie restante de la collection en deux. Le tableau est trié à l’aide du StringComparer.CurrentCulture. La fonction ShowWhere locale affiche des informations sur l’emplacement où la chaîne a été trouvée. Si la chaîne n’a pas été trouvée, la valeur retournée indique où elle se trouverait.
string[] lines =
[
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
];
Array.Sort(lines, StringComparer.CurrentCulture);
string searchString = @"c:\public\TEXTFILE.TXT";
Console.WriteLine($"Binary search for <{searchString}>");
int result = Array.BinarySearch(lines, searchString, StringComparer.CurrentCulture);
ShowWhere<string>(lines, result);
Console.WriteLine($"{(result > 0 ? "Found" : "Did not find")} {searchString}");
void ShowWhere<T>(T[] array, int index)
{
if (index < 0)
{
index = ~index;
Console.Write("Not found. Sorts between: ");
if (index == 0)
{
Console.Write("beginning of sequence and ");
}
else
{
Console.Write($"{array[index - 1]} and ");
}
if (index == array.Length)
{
Console.WriteLine("end of sequence.");
}
else
{
Console.WriteLine($"{array[index]}.");
}
}
else
{
Console.WriteLine($"Found at index {index}.");
}
}
Tri et recherche ordinales dans les collections
Le code suivant utilise la System.Collections.Generic.List<T> classe de collection pour stocker des chaînes. Les chaînes sont triées à l’aide de la List<T>.Sort méthode. Cette méthode a besoin d’un délégué qui compare et commande deux chaînes. La String.CompareTo méthode fournit cette fonction de comparaison. Exécutez l’exemple et observez l’ordre. Cette opération de tri utilise un tri sensible à la casse ordinale. Vous utiliseriez les méthodes statiques String.Compare pour spécifier différentes règles de comparaison.
List<string> lines =
[
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
];
Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}
Console.WriteLine("\n\rSorted order:");
lines.Sort((left, right) => left.CompareTo(right));
foreach (string s in lines)
{
Console.WriteLine($" {s}");
}
Une fois triées, la liste des chaînes peut être recherchée à l’aide d’une recherche binaire. L’exemple suivant montre comment effectuer une recherche dans la liste triée à l’aide de la même fonction de comparaison. La fonction ShowWhere locale indique où le texte recherché est ou serait :
List<string> lines =
[
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
];
lines.Sort((left, right) => left.CompareTo(right));
string searchString = @"c:\public\TEXTFILE.TXT";
Console.WriteLine($"Binary search for <{searchString}>");
int result = lines.BinarySearch(searchString);
ShowWhere<string>(lines, result);
Console.WriteLine($"{(result > 0 ? "Found" : "Did not find")} {searchString}");
void ShowWhere<T>(IList<T> collection, int index)
{
if (index < 0)
{
index = ~index;
Console.Write("Not found. Sorts between: ");
if (index == 0)
{
Console.Write("beginning of sequence and ");
}
else
{
Console.Write($"{collection[index - 1]} and ");
}
if (index == collection.Count)
{
Console.WriteLine("end of sequence.");
}
else
{
Console.WriteLine($"{collection[index]}.");
}
}
else
{
Console.WriteLine($"Found at index {index}.");
}
}
Veillez toujours à utiliser le même type de comparaison pour le tri et la recherche. L’utilisation de différents types de comparaison pour le tri et la recherche produit des résultats inattendus.
Les classes de collection telles que System.Collections.Hashtable, System.Collections.Generic.Dictionary<TKey,TValue> et System.Collections.Generic.List<T> ont des constructeurs qui prennent un paramètre System.StringComparer lorsque le type des éléments ou des clés est string. En général, vous devez utiliser ces constructeurs dans la mesure du possible, et spécifier soit StringComparer.Ordinal, soit StringComparer.OrdinalIgnoreCase.