Привет: у меня есть 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;
}
}