Partilhar via


Como: comparar seqüências de caracteres (guia de programação do C#)

Quando você compara cadeias de caracteres, você está gerando um resultado que digam que uma cadeia de caracteres é maior que ou menor que o outro, ou se as duas cadeias de caracteres são iguais.As regras por que o resultado é determinado são diferentes dependendo se você estiver executando a comparação ordinal ou a comparaçãoculture-sensitive.É importante usar o tipo correto de comparação para a tarefa específica.

Use comparações ordinais básicas quando você tem que compara ou classificar os valores das duas cadeias de caracteres sem considerar as convenções linguísticas.Uma comparação ordinal básica (System.StringComparison.Ordinal) diferencia maiúsculas de minúsculas, o que significa que as duas cadeias de caracteres devem coincidir com o caractere para o caractere: “e” não é igual a “e” ou “)”.Uma variação frequentemente- é usadaSystem.StringComparison.OrdinalIgnoreCase, que corresponderão “e”, “e”,” e “).StringComparison.OrdinalIgnoreCase é frequentemente usado para comparar nomes de arquivo, nomes de caminho, caminhos de rede, e qualquer outra cadeia de caracteres cujo valor não é alterada com base na localidade do computador do usuário.Para obter mais informações, consulte System.StringComparison.

As comparações que levam são normalmente usadas para comparar e classificar as cadeias de caracteres que são entradas por usuários finais, porque caracteres e convenções de classificação dessas cadeias de caracteres podem variar dependendo da localidade do computador do usuário.Mesmo cadeias de caracteres que contêm caracteres idênticos podem classificar de maneira diferente dependendo da cultura de segmento atual.

ObservaçãoObservação

Quando você compara cadeias de caracteres, você deve usar os métodos que especificam explicitamente o tipo de comparação você pretende executar.Isso torna seu código muito mais sustentável e legível.Sempre que possível, use as sobrecargas de métodos de classes de System.String e de System.Array que têm um parâmetro de enumeração de StringComparison , para que você possa especificar o tipo de comparação para executar.É melhor evitar usar os operadores de == e de != quando você compara cadeias de caracteres.Além disso, evite usar os métodos de instância de String.CompareTo porque nenhuma das sobrecargas leva StringComparison.

Exemplo

O exemplo a seguir mostra como comparar corretamente as cadeias de caracteres cujos valores não serão alteradas com base na localidade do computador do usuário.Além disso, também demonstra a cadeia de caracteres que interna o recurso C#.Quando um programa declarar variáveis de cadeia de caracteres dois ou mais idênticos, o compilador armazená-las todos no mesmo local.Chamando o método de ReferenceEquals , você pode ver que as duas cadeias de caracteres realmente referem-se ao mesmo objeto na memória.Use o método de String.Copy para evitar internar, conforme mostrado no exemplo.


// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";

// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);

Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
                    result ? "equal." : "not equal.");

// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
                     result ? "equal." : "not equal.");

// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);


// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";

// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
    Console.WriteLine("a and b are interned.");
else
    Console.WriteLine("a and b are not interned.");

// Use String.Copy method to avoid interning.
string c = String.Copy(a);

if (String.ReferenceEquals(a, c))
    Console.WriteLine("a and c are interned.");
else
    Console.WriteLine("a and c are not interned.");

// Output:
// Ordinal comparison: C:\users and C:\Users are not equal.
// Ordinal ignore case: C:\users and C:\Users are equal.
// a and b are interned.
// a and c are not interned.

O exemplo a seguir mostra como comparar cadeias de caracteres a maneira preferencial usando os métodos de System.String que recebem uma enumeração de StringComparison .Observe que os métodos de instância de String.CompareTo não são usados aqui, porque nenhuma das sobrecargas leva StringComparison.

// "They dance in the street."
// Linguistically (in Windows), "ss" is equal to 
// the German essetz: 'ß' character in both en-US and de-DE cultures.
string first = "Sie tanzen in die Straße."; 
string second = "Sie tanzen in die Strasse.";

Console.WriteLine("First sentence is {0}", first);
Console.WriteLine("Second sentence is {0}", second);

// Store CultureInfo for the current culture. Note that the original culture
// can be set and retrieved on the current thread object.
System.Threading.Thread thread = System.Threading.Thread.CurrentThread;
System.Globalization.CultureInfo originalCulture = thread.CurrentCulture;

// Set the culture to en-US.
thread.CurrentCulture = 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, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", originalCulture.Name, i);

// Change the current culture to Deutch-Deutchland.
thread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");
i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", thread.CurrentCulture.Name, i);

// For culture-sensitive string equality, use either StringCompare as above
// or the String.Equals overload that takes a StringComparison value.
thread.CurrentCulture = originalCulture;
bool b = String.Equals(first, second, StringComparison.CurrentCulture);
Console.WriteLine("The two strings {0} equal.", b == true ? "are" : "are not");

/*
 * Output:
    First sentence is Sie tanzen in die Straße.
    Second sentence is Sie tanzen in die Strasse.
    Comparing in current culture returns 0.
    The two strings are equal.
 */

O exemplo a seguir mostra como classificar e procurar por cadeias de caracteres em uma matriz em uma maneira culture-sensitive usando os métodos estáticos de Array que têm um parâmetro de System.StringComparer .

    class SortStringArrays
    {
        static void Main()
        {

            string[] lines = new string[]
            {
                @"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("   {0}", s);
            }

            Console.WriteLine("\n\rSorted order:");

            // Specify Ordinal to demonstrate the different behavior.
            Array.Sort(lines, StringComparer.Ordinal);

            foreach (string s in lines)
            {
                Console.WriteLine("   {0}", s);
            }


            string searchString = @"c:\public\TEXTFILE.TXT";
            Console.WriteLine("Binary search for {0}", searchString);
            int result = Array.BinarySearch(lines, searchString, StringComparer.OrdinalIgnoreCase);
            ShowWhere<string>(lines, result);

            //Console.WriteLine("{0} {1}", result > 0 ? "Found" : "Did not find", searchString);

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }

        // Displays where the string was found, or, if not found,
        // where it would have been located.
        private static void ShowWhere<T>(T[] array, int index)
        {
            if (index < 0)
            {
                // If the index is negative, it represents the bitwise
                // complement of the next larger element in the array.
                index = ~index;

                Console.Write("Not found. Sorts between: ");

                if (index == 0)
                    Console.Write("beginning of array and ");
                else
                    Console.Write("{0} and ", array[index - 1]);

                if (index == array.Length)
                    Console.WriteLine("end of array.");
                else
                    Console.WriteLine("{0}.", array[index]);
            }
            else
            {
                Console.WriteLine("Found at index {0}.", index);
            }
        }


    }
    /*
     * Output:
        Non-sorted order:
           c:\public\textfile.txt
           c:\public\textFile.TXT
           c:\public\Text.txt
           c:\public\testfile2.txt

        Sorted order:
           c:\public\Text.txt
           c:\public\testfile2.txt
           c:\public\textFile.TXT
           c:\public\textfile.txt
        Binary search for c:\public\TEXTFILE.TXT
        Found at index 2.
     */

A coleção classe como System.Collections.Hashtable, System.Collections.Generic.Dictionary<TKey, TValue>, e System.Collections.Generic.List<T> tem construtores que têm um parâmetro de System.StringComparer quando o tipo dos elementos ou teclas é string.Em geral, você deve usar esses construtores sempre que possível, e especifica Ordinal ou OrdinalIgnoreCase.

Consulte também

Referência

System.Globalization.CultureInfo

System.StringComparer

Conceitos

Comparação de seqüências de caracteres

Outros recursos

Seqüências de caracteres (guia de programação do C#)

Globalizando e Localizando aplicativos