Como pesquisar em cadeias de caracteres

Você pode usar duas estratégias principais para pesquisar texto em cadeias de caracteres. Os métodos da classe String pesquisam por um texto específico. Expressões regulares pesquisam por padrões no texto.

Observação

Os exemplos de C# neste artigo são executados no executador de código embutido Try.NET e no playground. Clique no botão Executar para executar um exemplo em uma janela interativa. Ao executar o código, é possível modificá-lo e executar o código modificado clicando em Executar novamente. O código modificado será executado na janela interativa ou, se a compilação falhar, a janela interativa exibirá todos as mensagens de erro do compilador C#.

O tipo string, que é um alias para a classe System.String, fornece uma série de métodos úteis para pesquisar o conteúdo de uma cadeia de caracteres. Entre elas estão Contains, StartsWith, EndsWith, IndexOf e LastIndexOf. A classe System.Text.RegularExpressions.Regex fornece um vocabulário avançado para pesquisar por padrões de texto. Neste artigo, você aprenderá essas técnicas e como escolher o melhor método para suas necessidades.

Uma cadeia de caracteres contém texto?

Os métodos String.Contains, String.StartsWith e String.EndsWith pesquisam uma cadeia de caracteres em busca de um texto específico. O seguinte exemplo mostra cada um desses métodos e uma variação que usa uma pesquisa que não diferencia maiúsculas de minúsculas:

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

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

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

// For user input and strings that will be displayed to the end user,
// use the StringComparison parameter on methods that have it to specify how to match strings.
bool ignoreCaseSearchResult = factMessage.StartsWith("extension", System.StringComparison.CurrentCultureIgnoreCase);
Console.WriteLine($"Starts with \"extension\"? {ignoreCaseSearchResult} (ignoring case)");

bool endsWithSearchResult = factMessage.EndsWith(".", System.StringComparison.CurrentCultureIgnoreCase);
Console.WriteLine($"Ends with '.'? {endsWithSearchResult}");

O exemplo anterior demonstra um ponto importante para usar esses métodos. As pesquisas de texto diferenciam maiúsculas e minúsculas por padrão. Use o valor de enumeração StringComparison.CurrentCultureIgnoreCase para especificar uma pesquisa que não diferencia maiúsculas de minúsculas.

Em que local de uma cadeia de caracteres o texto procurado ocorre?

Os métodos IndexOf e LastIndexOf também pesquisam texto em cadeias de caracteres. Esses métodos retornam o local do texto que está sendo procurado. Se o texto não for encontrado, elas retornarão -1. O exemplo a seguir mostra uma pesquisa para a primeira e a última ocorrência da palavra "métodos" e exibe o texto entre elas.

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

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

// This search returns the substring between two strings, so
// the first index is moved to the character just after the first string.
int first = factMessage.IndexOf("methods") + "methods".Length;
int last = factMessage.LastIndexOf("methods");
string str2 = factMessage.Substring(first, last - first);
Console.WriteLine($"Substring between \"methods\" and \"methods\": '{str2}'");

Localizar texto específico usando expressões regulares

A classe System.Text.RegularExpressions.Regex pode ser usada para pesquisar cadeias de caracteres. Essas pesquisas podem variar em complexidade, de padrões de texto simples até os complicados.

O exemplo de código a seguir procura a palavra "the" ou "their" em uma oração, sem diferenciar maiúsculas e minúsculas. O método estático Regex.IsMatch realiza a pesquisa. Você fornece a ele a cadeia de caracteres a pesquisar e um padrão de pesquisa. Nesse caso, um terceiro argumento especifica que a pesquisa não diferencia maiúsculas de minúsculas. Para obter mais informações, consulte System.Text.RegularExpressions.RegexOptions.

O padrão de pesquisa descreve o texto pelo qual procurar. A tabela a seguir descreve cada elemento desse padrão de pesquisa. (A tabela abaixo usa a única \, que deve ser escapada como \\ em uma cadeia de caracteres C#).

Padrão Significado
the corresponder ao texto "the"
(eir)? corresponder a 0 ou 1 ocorrência de "eir"
\s corresponder a um caractere de espaço em branco
string[] sentences =
{
    "Put the water over there.",
    "They're quite thirsty.",
    "Their water bottles broke."
};

string sPattern = "the(ir)?\\s";

foreach (string s in sentences)
{
    Console.Write($"{s,24}");

    if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
    {
        Console.WriteLine($"  (match for '{sPattern}' found)");
    }
    else
    {
        Console.WriteLine();
    }
}

Dica

Os métodos string são geralmente melhores opções quando você está procurando por uma cadeia de caracteres exata. Expressões regulares são melhores quando você está procurando por algum padrão em uma cadeia de caracteres de origem.

Uma cadeia de caracteres segue um padrão?

O código a seguir usa expressões regulares para validar o formato de cada cadeia de caracteres em uma matriz. A validação requer que cada cadeia de caracteres tenha a forma de um número de telefone no qual os três grupos de dígitos são separados por traços, os dois primeiros grupos contêm três dígitos e o terceiro grupo contém quatro dígitos. O padrão de pesquisa usa a expressão regular ^\\d{3}-\\d{3}-\\d{4}$. Para obter mais informações, consulte Linguagem de expressões regulares – referência rápida.

Padrão Significado
^ corresponde ao início da cadeia de caracteres
\d{3} corresponde a exatamente 3 caracteres de dígitos
- corresponde ao caractere '-'
\d{4} corresponde a exatamente 4 caracteres de dígitos
$ corresponde ao final da cadeia de caracteres
string[] numbers =
{
    "123-555-0190",
    "444-234-22450",
    "690-555-0178",
    "146-893-232",
    "146-555-0122",
    "4007-555-0111",
    "407-555-0111",
    "407-2-5555",
    "407-555-8974",
    "407-2ab-5555",
    "690-555-8148",
    "146-893-232-"
};

string sPattern = "^\\d{3}-\\d{3}-\\d{4}$";

foreach (string s in numbers)
{
    Console.Write($"{s,14}");

    if (System.Text.RegularExpressions.Regex.IsMatch(s, sPattern))
    {
        Console.WriteLine(" - valid");
    }
    else
    {
        Console.WriteLine(" - invalid");
    }
}

Este padrão de pesquisa único corresponde a várias cadeias de caracteres válidas. Expressões regulares são melhores para pesquisar por ou validar mediante um padrão, em vez de uma única cadeia de caracteres de texto.

Confira também