Выделить текст в элементе управления RichTextBox

#c# #winforms #richtextbox #highlight

#c# #winforms #richtextbox #выделить

Вопрос:

Я пытаюсь выделить несколько строк определенного текста в RichTextBox.
Вот мой код для выделения текста:

 public void HighlightMistakes(RichTextBox richTextBox)
{
    string[] phrases =  { "Drivers Do Not Match", "Current Does Not Match", "No Drivers Found" };      
    foreach (var phrase in phrases)
    {
        int startIndex = 0;
        while (startIndex <= richTextBox.TextLength)
        {
            int phraseStartIndex = richTextBox.Find(phrase, startIndex, RichTextBoxFinds.None);
            if (phraseStartIndex != -1)
            {
                richTextBox.SelectionStart = phraseStartIndex;
                richTextBox.SelectionLength = phrase.Length;
                richTextBox.SelectionBackColor = Color.Yellow;
            }
            else break;
            startIndex  = phraseStartIndex   phrase.Length;
        }
    }
}  
  

Вот как я добавляю текст в RTB и вызываю функцию выше:

 foreach (var a in resultList)
{
    richTextBox1.AppendText("n" a   "n");
    HighlightMistakes(richTextBox1);
}
  

Однако HighlightMistakes работает не так, как мне бы хотелось. Идея состоит в том, чтобы выделить все строковые значения, указанные в phrases массиве, и это происходит не каждый раз.

Примеры:

введите описание изображения здесь

введите описание изображения здесь

Я не уверен, почему некоторые строки пропущены, а некоторые нет.

Комментарии:

1. Вы пробовали отладчик , вашего самого лучшего друга в мире кодирования.

2. Подумайте: у вас есть SelectionStart = phraseStartIndex — это означает phraseStartIndex , что включает расстояние от начала текста и уже учитывает startIndex значение. Затем вы добавляете phraseStartIndex в startIndex , что означает, что вы устанавливаете startIndex значение startIndex startIndex phraseOffset phrase.Length , чтобы пропустить текст. Не добавлять, устанавливать startIndex = phraseStartIndex phrase.Length

3. @NetMage, спасибо за предложение, но если я это сделаю, программа зависнет, и приложение перейдет в режим перерыва:(

4. @NetMage однако, когда я удаляю phraseStartIndex из уравнения, повторяющиеся строки больше не пропускаются. Спасибо за подсказку. Теперь у меня есть startIndex = phrase.Length

5. Я не думаю, что это правильно — вероятно, он помечает фразы несколько раз. Вы уверены, что пробовали startIndex = phraseStartIndex phrase.Length; ? Моя тестовая программа отлично работает, когда я делаю это с вашими примерами.

Ответ №1:

Если вы ничего не имеете против простого метода регулярных выражений, вы можете использовать Regex.Совпадения для сопоставления вашего списка фраз с текстом вашего RichTextBox.
Каждое совпадение в коллекции совпадений содержит как индекс (позицию внутри текста), где найдено совпадение, так и его длину, поэтому вы можете просто вызвать .Выберите (индекс, длина), чтобы выбрать фразу и выделить ее.
Используемый шаблон представляет собой строку, полученную в результате объединения фраз для сопоставления с каналом ( | ).
Каждая фраза передается в Regex.Escape(), поскольку текст может содержать метасимволы.

Если вы хотите рассмотреть этот случай, удалите RegexOptions.IgnoreCase .

 using System.Text.RegularExpressions;

string[] phrases = { "Drivers Do Not Match",
                     "Current Does Not Match",
                     "No Drivers Found" };
HighlightMistakes(richTextBox1, phrases);

private void HighlightMistakes(RichTextBox rtb, string[] phrases)
{
    ClearMistakes(rtb);
    string pattern = string.Join("|", phrases.Select(phr => Regex.Escape(phr)));

    var matches = Regex.Matches(rtb.Text, pattern, RegexOptions.IgnoreCase);
    foreach (Match m in matches) {
        rtb.Select(m.Index, m.Length);
        rtb.SelectionBackColor = Color.Yellow;
    }
}

private void ClearMistakes(RichTextBox rtb)
{
    int selStart = rtb.SelectionStart;
    rtb.SelectAll();
    rtb.SelectionBackColor = rtb.BackColor;
    rtb.SelectionStart = selStart;
    rtb.SelectionLength = 0;
}