Форматирование текста в WPF RichTextBox с несколькими регулярными выражениями - PullRequest
0 голосов
/ 18 апреля 2020

Привет: у меня есть C# WPF-приложение с RichTextBox, к которому я применяю автоматическое c форматирование на основе определенных символов форматирования, например, $ word $ (в окружении знаков $) может быть желтым, а # Word # (в окружении знаков #) может быть красным, и т. д. c ... Совпадения слов получаются в результате нескольких запросов по регулярным выражениям Проблемы отслеживания позиций смещения в RichTextBox из-за невидимых символов форматирования при выборе и форматировании нескольких запросов на регулярное выражение в партиях хорошо задокументированы.

Поэтому я реализовал следующий метод грубой силы, который объединяет все совпадения регулярного выражения в различные регулярные выражения выполняют поиск в одном списке, сортируя список по индексу, чтобы затем форматирование можно было применять последовательно (слева направо), сопоставляя его с соответствующим смещением, применяемым после каждого форматирования.

код работает, но медленно. Буду признателен за любые отзывы о (1) способах ускорения этого кода и (2) возможно о любых альтернативных подходах, которые были бы значительно более эффективными.

public class SearchResult
{
    public string FormatType { get; set; }
    public int ResultIndex { get; set; }
    public int ResultLength { get; set; }
}

public static void FormatText(RichTextBox richTextBox)
{
    // List comprise of SearchResult entries
    var SearchResults = new List<SearchResult>();

    // Get RichTextBox TextRange to be formatted
    TextRange textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);

    // Initialize the formatting
    textRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.White);

    // First Regular Expression search to find all words surrounded by dollar signs
    Regex regexDollar = new Regex(@"(\$.*?\$)", RegexOptions.Compiled);
    MatchCollection matchesDollar = regexDollar.Matches(textRange.Text);

    // All matches added to SearchResults list
    foreach(Match match in matchesDollar)
    {
        SearchResult searchResult = new SearchResult();
        searchResult.FormatType = "FormatDollar";
        searchResult.ResultIndex = match.Index;
        searchResult.ResultLength = match.Length;
        SearchResults.Add(searchResult);
    }

    // Second Regular Expression search to find all words surrounded by pound signs
    Regex regexPound = new Regex(@"(\#.*?\#)", RegexOptions.Compiled);
    MatchCollection matchesPound = regexPound.Matches(textRange.Text);

    // All matches added to SearchResults list
    foreach (Match match in matchesPound)
    {
        SearchResult searchResult = new SearchResult();
        searchResult.FormatType = "FormatPound";
        searchResult.ResultIndex = match.Index;
        searchResult.ResultLength = match.Length;
        SearchResults.Add(searchResult);
    }

    // Sort the list of all of the match results based on index
    List<SearchResult> SortedSearchResults = SearchResults.OrderBy(sr => sr.ResultIndex).ToList();

    // Initialize offset variable
    int i = 0;


    foreach (SearchResult sr in SortedSearchResults)
    {
        // For each SearchResult, select the corresponding word based on index, length and offset.
        TextPointer start = textRange.Start.GetPositionAtOffset(i + sr.ResultIndex);
        TextPointer end = textRange.Start.GetPositionAtOffset(i + sr.ResultIndex + sr.ResultLength);

        // Format the selected text based on the FormatType.
        switch (sr.FormatType)
        {
            case "FormatDollar":
                new TextRange(start, end).ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Yellow);
                break;
            case "FormatPound":
                new TextRange(start, end).ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
                break;
            default:
                break;
        }

        // Increment the offset variable.
        i += 4;
    }
}
...