练习 - 使用字符串的 IndexOf() 和 LastIndexOf() 帮助程序方法
- 25 分钟
本练习使用 IndexOf() 和 LastIndexOf() 方法查找给定字符串中字符和子字符串的位置。
IndexOf() 和 LastIndexOf
.IndexOf() 方法返回给定字符串中指定字符或子字符串的第一个匹配项的索引。
.LastIndexOf() 方法返回给定字符串中字符或字符串的最后一个匹配项的索引位置。 如果未找到字符或字符串,Indexof() 和 LastIndexOf() 方法均返回 -1。
选择并删除 Visual Studio Code 编辑器中的所有代码行。
在 Visual Studio Code 编辑器中更新代码,如下所示:
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}.");保存代码文件,然后使用 Visual Studio Code 运行代码。 应会看到以下输出:
For the message: 'hello there!', the first 'h' is at position 0 and the last 'h' is at position 7.输出标识了字符串“hello there!”中位置 0 处的第一个“h”和位置 7 处的最后一个“h”。
检索子字符串的最后一个匹配项
通过添加多对括号来增加 message 变量的复杂性,然后编写代码以检索最后一组括号内的内容。
选择并删除 Visual Studio Code 编辑器中的所有代码行。
在 Visual Studio Code 编辑器中更新代码,如下所示:
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));保存代码文件,然后使用 Visual Studio Code 运行代码。 应会看到以下输出:
set of parentheses此示例的关键是使用
LastIndexOf()获取最后一个左括号和右括号的位置。注意
前面的示例代码运行时不会出现错误,因为
message字符串包含格式正确的括号对。 但是该代码易被破坏,当不存在括号对时,或当最后的括号没有形成开括号和闭括号对时,该代码就会产生错误。
检索括号内子字符串的所有实例
这次,将 message 更新为包含三组括号,并且编写代码来提取括号中的文本。 你将能够重复使用一部分以前的工作,但是需要添加 while 语句来循环访问字符串,直到发现、提取并显示所有括号为止。
在 Visual Studio Code 编辑器中更新代码,如下所示:
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); }保存代码文件,然后使用 Visual Studio Code 运行代码。 应会看到以下输出:
What if more than set of parentheses花一分钟观察
while循环中的最后一行代码,在以下代码中拉取:message = message.Substring(closingPosition + 1);使用
Substring()而不指定长度输入参数时,将返回指定的起始位置之后的每个字符。 处理字符串时,message = "(What if) there are (more than) one (set of parentheses)?",从(What if)的值中删除第一组括号message是有好处的。 然后在while循环的下一次迭代中处理剩余的内容。花一分钟考虑在
while循环的最终迭代期间,当仅保留最后的?字符时会发生什么情况。以下代码用于处理字符串末尾:
int openingPosition = message.IndexOf('('); if (openingPosition == -1) break;如果在字符串中找不到输入参数,则
IndexOf()方法将返回-1。 你只检查循环外的值-1和break。
使用 IndexOfAny() 处理不同类型的符号集
这一次,使用 .IndexOfAny() 搜索几个不同的字符符号,而不仅仅是一组括号。
.IndexOfAny() 报告提供的字符数组中任意字符的第一个匹配项的索引。 如果未在字符数组中找到任何字符,则该方法返回 -1。
在以下示例中,返回了找到的第一个“a”、“e”或“i”字符的索引。
在 Visual Studio Code 编辑器中更新代码,如下所示:
string message = "Hello, world!"; char[] charsToFind = { 'a', 'e', 'i' }; int index = message.IndexOfAny(charsToFind); Console.WriteLine($"Found '{message[index]}' in '{message}' at index: {index}.");保存代码文件,然后使用 Visual Studio Code 运行代码。
应会看到以下输出:
Found 'e' in 'Hello, world!' at index: 1.将添加不同类型符号(如方括号
message和大括号[])来更新{}字符串。 若要同时搜索多个符号,请使用.IndexOfAny()。 使用.IndexOfAny()进行搜索,以从openSymbols字符串中找到的数组message中返回第一个符号的索引。在 Visual Studio Code 编辑器中更新代码,如下所示:
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)}");保存代码文件,然后使用 Visual Studio Code 运行代码。
应会看到以下输出:
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}花一分钟检查一下之前输入的代码。
你使用了
.IndexOfAny()without,然后又使用了 with,导致起始位置重载。找到开始符号后,需要查找其匹配的结束符号。
在 Visual Studio Code 编辑器中更新代码,如下所示:
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)); }花几分钟时间检查前面的代码并阅读有助于说明代码的注释。
继续检查代码,并使用
IndexOf()找到以下代码行来定义closingPosition:closingPosition = message.IndexOf(matchingSymbol, openingPosition);变量
closingPosition用于查找传递到方法Substring()的长度,并查找下一个openingPosition值:int openingPosition = message.IndexOfAny(openSymbols, closingPosition);因此,会在
closingPosition循环范围外定义while变量并在第一次迭代时将其初始化为0。保存代码文件,然后使用 Visual Studio Code 运行代码。 应会看到以下输出:
What if different symbols open symbol matching closing symbol
概括
此处需要谨记两个要点:
-
LastIndexOf()返回字符或字符串在另一个字符串中最后出现的位置。 -
IndexOfAny()返回在另一个字符串内首次出现char数组的位置。