Pesquisar cadeias de caracteres em C#

Dica

Este artigo faz parte da seção Conceitos Básicos para desenvolvedores que já conhecem pelo menos uma linguagem de programação e estão aprendendo C#. Se você é novo em programação, comece com os tutoriais Comece agora.

Vindo de outro idioma? Métodos C# string, como Contains, StartsWith e IndexOf, têm métodos paralelos em String do Java e String.prototype do JavaScript. A principal diferença é que algumas buscas em C# usam por padrão a comparação ordinal, que diferencia maiúsculas de minúsculas. Outros usam por padrão a semântica da cultura vigente. Para pesquisas voltadas para o usuário, talvez você queira passar um StringComparison valor.

A String classe inclui métodos que respondem a duas perguntas diárias:

Algoritmos de pesquisa e substituição mais complexos podem ser criados usando expressões regulares. Para obter mais informações sobre expressões regulares e outras operações de cadeia de caracteres, consulte o artigo de referência de idioma sobre operações de cadeia de caracteres.

Verificar se uma cadeia de caracteres contém texto

Use Contains, StartsWith ou EndsWith para testar a presença de uma subcadeia:

string factMessage = "Extension methods have all the capabilities of regular static methods.";

// Write the string and include the quotation marks.
Console.WriteLine($"\"{factMessage}\"");

// Default comparisons are case sensitive.
bool containsSearchResult = factMessage.Contains("extension");
Console.WriteLine($"""Contains "extension"? {containsSearchResult}""");

// For user-facing searches, pass a StringComparison value to control case and culture.
bool ignoreCaseSearchResult = factMessage.StartsWith("extension", StringComparison.CurrentCultureIgnoreCase);
Console.WriteLine($"""Starts with "extension"? {ignoreCaseSearchResult} (ignoring case)""");

bool endsWithSearchResult = factMessage.EndsWith(".", StringComparison.Ordinal);
Console.WriteLine($"Ends with '.'? {endsWithSearchResult}");
// => "Extension methods have all the capabilities of regular static methods."
// => Contains "extension"? False
// => Starts with "extension"? True (ignoring case)
// => Ends with '.'? True

Esses métodos usam por padrão a comparação com diferenciação entre maiúsculas e minúsculas e ordinal. Para aceitar a entrada do usuário ou ignorar diferenças entre maiúsculas e minúsculas para texto de exibição, passe um valor StringComparison, como StringComparison.CurrentCultureIgnoreCase ou StringComparison.OrdinalIgnoreCase.

Ao procurar um único caractere, use a sobrecarga char de Contains. Ele evita alocar uma string de 1 caractere e é mais direto:

string path = "/usr/local/bin";
bool hasSlash = path.Contains('/');
Console.WriteLine($"Path contains '/': {hasSlash}");
// => Path contains '/': True

Localizar a posição do texto

IndexOf retorna o índice baseado em zero da primeira ocorrência de uma subcadeia de caracteres (ou caractere) e LastIndexOf retorna o índice da última ocorrência. Ambos retornam -1 quando o texto de pesquisa não está presente. Combine-os para extrair o texto entre dois marcadores:

string factMessage = "Extension methods have all the capabilities of regular static methods.";

Console.WriteLine($"\"{factMessage}\"");

// Extract the text between the first and last occurrence of "methods".
int first = factMessage.IndexOf("methods") + "methods".Length;
int last = factMessage.LastIndexOf("methods");
string between = factMessage.Substring(first, last - first);
Console.WriteLine($"""Substring between "methods" and "methods": '{between}'""");
// => "Extension methods have all the capabilities of regular static methods."
// => Substring between "methods" and "methods": ' have all the capabilities of regular static '

Quando você precisar de todas as ocorrências em vez da primeira ou da última, itere passando o resultado anterior mais um como o argumento startIndex, ou alterne para uma expressão regular.

Escolher a comparação correta

A maioria das sobrecargas de pesquisa aceita um valor opcional StringComparison . Escolha-o com base no tipo de dados que você está pesquisando:

  • Se você estiver pesquisando identificadores, caminhos de arquivo, tokens de protocolo ou qualquer outra coisa definida pelo computador, use Ordinal.
  • Se você estiver pesquisando o mesmo tipo de dados definidos por máquina, mas quiser pesquisar sem diferenciar maiúsculas de minúsculas, use OrdinalIgnoreCase.
  • Se você estiver pesquisando texto visível para o usuário ao qual devem se aplicar as regras da localidade atual, use CurrentCulture.
  • Se você estiver procurando esse mesmo texto visível para o usuário e quiser ignorar a diferenciação entre maiúsculas e minúsculas, use CurrentCultureIgnoreCase.
  • Se você estiver pesquisando dados persistentes que devem produzir o mesmo resultado de comparação em todas as máquinas e culturas, use InvariantCulture (raramente é necessário).

A comparação ordinal é a opção mais rápida e o padrão correto para qualquer coisa que não seja texto em linguagem natural. A comparação sensível à cultura é significativamente mais lenta e pode produzir resultados surpreendentes. Por exemplo, em algumas culturas, a versão minúscula i não corresponde à versão maiúscula I. Reserve isso para pesquisas que os usuários fazem em texto corrido.

Para uma abordagem detalhada da comparação sensível à cultura, consulte Práticas recomendadas para comparar cadeias de caracteres.

Consulte também