練習 - 使用字串的 IndexOfAny() 和 LastIndexOf() 協助程式方法

已完成

在此練習中,您會使用 IndexOfAny() 方法來尋找所選取陣列中任何 string 的第一個位置。 您也可以使用 LastIndexOf() 來尋找另一個字串內字串的最終位置。

擷取最後一次出現的子字串

您會藉由新增多組括弧以增加 message 變數的複雜度,然後撰寫程式碼以擷取「最後」一組括弧內的內容。

  1. 選取並刪除 Visual Studio Code 編輯器中的所有程式碼行。

  2. 在 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));
    
  3. 儲存您的程式碼檔案,然後使用 Visual Studio Code 來執行程式碼。 您應該會看見下列輸出:

    set of parentheses
    

    這個範例的關鍵在於使用 LastIndexOf(),以取得最後一個左右括弧的位置。

擷取括弧內的所有子字串執行個體

這次,將 message 更新為擁有三組括弧,並將撰寫程式碼以擷取括弧內的所有文字。 您可以重複使用前面的部分程式碼,但您需新增 while 陳述式來逐一查看字串,直到已找到、擷取和顯示所有的括弧組合為止。

  1. 在 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);
    }
    
  2. 儲存您的程式碼檔案,然後使用 Visual Studio Code 來執行程式碼。 您應該會看見下列輸出:

    What if
    more than
    set of parentheses
    
  3. 請花一分鐘的時間觀察 while 迴圈中的最後一行程式碼,並提取在下列程式碼中:

    message = message.Substring(closingPosition + 1);
    

    當您使用 Substring() 而不指定長度輸入參數時,程式碼會傳回您所指定起始位置之後的每個字元。 對於正在處理的字串,message = "(What if) there are (more than) one (set of parentheses)?",從 message 值中删除第一組括弧 (What if) 是有好處的。 接著會在 while 迴圈的下一個反覆項目中處理剩餘工作。

  4. 請花一分鐘的時間來考慮,只保留最終 while 字元時,? 迴圈的最終反覆項目期間會發生什麼情況。

    下列程式碼會處理字串結尾:

    int openingPosition = message.IndexOf('(');
    if (openingPosition == -1) break;
    

    如果 IndexOf() 方法在字串中找不到輸入參數,則會傳回 -1。 而您只會在迴圈外檢查 -1break 的值。

使用不同類型的符號集

這次,請搜尋數個不同的符號,而不只是一組括弧。

更新 message 字串,新增不同類型的符號,例如方括弧 [] 和大括弧 {}。 若要同時搜尋多個符號,請使用 .IndexOfAny()。 您可以使用 .IndexOfAny() 進行搜尋,從 message 字串中找到的陣列 openSymbols 傳回第一個符號的索引。

  1. 在 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)}");
    
  2. 儲存您的程式碼檔案,然後使用 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}
    
  3. 請花幾分鐘檢閱先前輸入的程式碼。

    您使用.IndexOfAny()不具,然後使用具有,開始位置多載。

    既然您已找到開頭符號,您需要尋找其相符的結尾符號。

  4. 在 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));
    }
    
  5. 花幾分鐘時間檢查以前的程式碼,並閱讀有助於説明程式碼的註解。

  6. 繼續檢查程式碼,並使用 IndexOf() 找出下列程式碼,以定義 closingPosition

    closingPosition = message.IndexOf(matchingSymbol, openingPosition);
    

    變數 closingPosition 用於尋找傳遞至 Substring() 方法的長度,並查找下一個 openingPosition 值:

    int openingPosition = message.IndexOfAny(openSymbols, closingPosition);
    

    因此,closingPosition 變數是定義於 while 迴圈範圍之外,並初始化為第一個反覆項目的 0

  7. 儲存您的程式碼檔案,然後使用 Visual Studio Code 來執行程式碼。 您應該會看見下列輸出:

    What if
    different symbols
    open symbol
    matching closing symbol
    

概括回顧

以下為需記住的兩個重點:

  • LastIndexOf() 可傳回其他字串內字元或字串的最後一個位置。
  • IndexOfAny() 可傳回出現在其他字串內 char 陣列的第一個位置。

檢定您的知識

1.

應該使用哪一種方法來搜尋長字串中第一次出現的搜尋字詞?