Exercício – Usar os métodos auxiliares IndexOf() e LastIndexOf() da cadeia de caracteres
- 25 minutos
Neste exercício, usamos os métodos IndexOf() e LastIndexOf() para localizar as posições de caracteres e subcadeias de caracteres dentro de uma determinada cadeia de caracteres.
IndexOf() e LastIndexOf
O método .IndexOf() retorna o índice da primeira ocorrência de um caractere ou cadeia de caracteres dentro de uma determinada cadeia de caracteres. O método .LastIndexOf() retorna a posição de índice da última ocorrência de um caractere ou cadeia de caracteres dentro de uma determinada cadeia de caracteres. Os métodos Indexof() e LastIndexOf() retornarão -1 se o caractere ou a cadeia de caracteres não forem encontrados.
Selecione e exclua todas as linhas de código no Editor de Visual Studio Code.
Atualize seu código no Editor do Visual Studio Code da seguinte maneira:
string message = "hello there!"; int first_h = message.IndexOf('h'); int last_h = message.LastIndexOf('h'); Console.WriteLine($"For the message: '{message}', the first 'h' is at position {first_h} and the last 'h' is at position {last_h}.");Salve o arquivo de código e use o Visual Studio Code para executar o código. A seguinte saída deve ser exibida:
For the message: 'hello there!', the first 'h' is at position 0 and the last 'h' is at position 7.O resultado identifica o primeiro "h" na cadeia de caracteres "hello there!" na posição 0 e o último "h" na posição 7.
Recuperar a última ocorrência de uma subcadeia de caracteres
Você pode aumentar a complexidade da variável message adicionando vários conjuntos de parênteses e, a seguir, escrever código para recuperar o conteúdo dentro do último conjunto de parênteses.
Selecione e exclua todas as linhas de código no Editor de Visual Studio Code.
Atualize seu código no Editor do Visual Studio Code da seguinte maneira:
string message = "(What if) I am (only interested) in the last (set of parentheses)?"; int openingPosition = message.LastIndexOf('('); openingPosition += 1; int closingPosition = message.LastIndexOf(')'); int length = closingPosition - openingPosition; Console.WriteLine(message.Substring(openingPosition, length));Salve o arquivo de código e use o Visual Studio Code para executar o código. A seguinte saída deve ser exibida:
set of parenthesesNeste exemplo, o uso de
LastIndexOf()é essencial, pois ele é empregado para obter as posições dos últimos parênteses de abertura e fechamento.Observação
O código de exemplo anterior só é executado sem erro porque a cadeia de caracteres
messagecontém pares de parênteses formatados corretamente. Mas o código é frágil e produz erros quando nenhum par de parênteses está presente ou quando os últimos parênteses não formam um par de abertura e fechamento.
Recuperar todas as instâncias de subcadeias de caracteres dentro de parênteses
Desta vez, você atualiza o message para ter três conjuntos de parênteses e escreve o código para extrair qualquer texto dentro dos parênteses. Você pode reutilizar partes do trabalho anterior, mas precisaremos adicionar uma instrução while para iterar pela cadeia de caracteres até que todos os conjuntos de parênteses sejam descobertos, extraídos e exibidos.
Atualize seu código no Editor do Visual Studio Code da seguinte maneira:
string message = "(What if) there are (more than) one (set of parentheses)?"; while (true) { int openingPosition = message.IndexOf('('); if (openingPosition == -1) break; openingPosition += 1; int closingPosition = message.IndexOf(')'); int length = closingPosition - openingPosition; Console.WriteLine(message.Substring(openingPosition, length)); // Note the overload of the Substring to return only the remaining // unprocessed message: message = message.Substring(closingPosition + 1); }Salve o arquivo de código e use o Visual Studio Code para executar o código. A seguinte saída deve ser exibida:
What if more than set of parenthesesReserve um minuto para observar a última linha de código dentro do loop
while, extraído no seguinte código:message = message.Substring(closingPosition + 1);Quando você usa
Substring()sem especificar um parâmetro de entrada de comprimento, ele retornará todos os caracteres após a posição inicial especificada. Com a cadeia de caracteres sendo processada,message = "(What if) there are (more than) one (set of parentheses)?", há uma vantagem em remover o primeiro conjunto de parênteses(What if)do valor demessage. O que permanece é processado na próxima iteração do loopwhile.Reserve um minuto para considerar o que acontece durante a iteração final do loop
while, quando apenas o caractere final?permanece.O código a seguir aborda a manipulação do final da cadeia de caracteres:
int openingPosition = message.IndexOf('('); if (openingPosition == -1) break;O método
IndexOf()retorna-1se não encontrar o parâmetro de entrada na cadeia de caracteres. Você apenas verificou o valor-1ebreakfora do loop.
Trabalhe com diferentes tipos de conjuntos de símbolos usando IndexOfAny()
Desta vez, pesquise vários símbolos de caracteres diferentes, não apenas um conjunto de parênteses, usando .IndexOfAny().
.IndexOfAny() informa o índice da primeira ocorrência de qualquer caractere em um array de caracteres fornecido. O método retornará -1 se todos os caracteres na matriz de caracteres figurarem como não encontrados.
No exemplo a seguir, o índice do primeiro caractere encontrado entre 'a', 'e' ou 'i' é retornado.
Atualize seu código no editor do Visual Studio Code da seguinte maneira:
string message = "Hello, world!"; char[] charsToFind = { 'a', 'e', 'i' }; int index = message.IndexOfAny(charsToFind); Console.WriteLine($"Found '{message[index]}' in '{message}' at index: {index}.");Salve o arquivo de código e use o Visual Studio Code para executar o código.
A seguinte saída deve ser exibida:
Found 'e' in 'Hello, world!' at index: 1.Atualize a cadeia de caracteres
messageadicionando tipos diferentes de símbolos, como colchetes[]e chaves{}. Para pesquisar vários símbolos simultaneamente, use.IndexOfAny(). Pesquise com.IndexOfAny()para retornar o índice do primeiro símbolo da matrizopenSymbolsencontrada na cadeia de caracteresmessage.Atualize seu código no editor do Visual Studio Code da seguinte maneira:
string message = "Help (find) the {opening symbols}"; Console.WriteLine($"Searching THIS Message: {message}"); char[] openSymbols = { '[', '{', '(' }; int startPosition = 5; int openingPosition = message.IndexOfAny(openSymbols); Console.WriteLine($"Found WITHOUT using startPosition: {message.Substring(openingPosition)}"); openingPosition = message.IndexOfAny(openSymbols, startPosition); Console.WriteLine($"Found WITH using startPosition {startPosition}: {message.Substring(openingPosition)}");Salve o arquivo de código e use o Visual Studio Code para executar o código.
A seguinte saída deve ser exibida:
Searching THIS message: Help (find) the {opening symbols} Found WITHOUT using startPosition: (find) the {opening symbols} Found WITH using startPosition 5: (find) the {opening symbols}Reserve um minuto para analisar o código inserido anteriormente.
Você usou
.IndexOfAny()sem e, em seguida, com a sobrecarga de posição inicial.Agora que você encontrou um símbolo de abertura, precisa encontrar o símbolo de fechamento correspondente.
Atualize seu código no Editor do Visual Studio Code da seguinte maneira:
string message = "(What if) I have [different symbols] but every {open symbol} needs a [matching closing symbol]?"; // The IndexOfAny() helper method requires a char array of characters. // You want to look for: char[] openSymbols = { '[', '{', '(' }; // You'll use a slightly different technique for iterating through // the characters in the string. This time, use the closing // position of the previous iteration as the starting index for the //next open symbol. So, you need to initialize the closingPosition // variable to zero: int closingPosition = 0; while (true) { int openingPosition = message.IndexOfAny(openSymbols, closingPosition); if (openingPosition == -1) break; string currentSymbol = message.Substring(openingPosition, 1); // Now find the matching closing symbol char matchingSymbol = ' '; switch (currentSymbol) { case "[": matchingSymbol = ']'; break; case "{": matchingSymbol = '}'; break; case "(": matchingSymbol = ')'; break; } // To find the closingPosition, use an overload of the IndexOf method to specify // that the search for the matchingSymbol should start at the openingPosition in the string. openingPosition += 1; closingPosition = message.IndexOf(matchingSymbol, openingPosition); // Finally, use the techniques you've already learned to display the sub-string: int length = closingPosition - openingPosition; Console.WriteLine(message.Substring(openingPosition, length)); }Reserve alguns minutos para examinar o código anterior e ler os comentários que ajudam a explicar o código.
Continue examinando o código e localize a seguinte linha de código usando
IndexOf()para definirclosingPosition:closingPosition = message.IndexOf(matchingSymbol, openingPosition);A variável
closingPositioné usada para encontrar o comprimento passado para o métodoSubstring()e para encontrar o próximo valoropeningPosition:int openingPosition = message.IndexOfAny(openSymbols, closingPosition);Por esse motivo, a variável
closingPositioné definida fora do loopwhilee inicializada para0na primeira iteração.Salve o arquivo de código e use o Visual Studio Code para executar o código. A seguinte saída deve ser exibida:
What if different symbols open symbol matching closing symbol
Recapitulação
Aqui estão dois pontos importantes a serem lembrados:
LastIndexOf()retorna a última posição de um caractere ou uma cadeia de caracteres dentro de outra cadeia de caracteres.IndexOfAny()retorna a primeira posição de uma matriz decharque ocorre dentro de outra cadeia de caracteres.