【问题标题】:Highlight text after pattern在模式后突出显示文本
【发布时间】:2022-12-03 02:52:51
【问题描述】:

我正在尝试创建一个基于模式的彩色丰富文本框。

正文是:

Hey, This{Red} IS A {Cyan}sample. The {Green}color is green color

每个{ } 都包含一种颜色,它是下一个单词的样式:

嘿,这个是一个sample. The 颜色是绿色

Hey, This 默认颜色。

IS A 应该是红色。

sample. The 应该是青色。

color is green color 应该是绿色的。

这是我的代码:

// Hey, This{Red} IS A {Cyan}sample. The {Green}color is green color
// shown text should be:
// Hey, This IS A sample. The color is green

const string OriginalText = "Hey, This{Red} IS A {Cyan}sample. The {Green}color is green color";
const string ShownText = "Hey, This IS A sample. The color is green color";
const string Pattern = "(?<=\\{)(.*?)(?=\\})";

rtbMain.Text = ShownText;

rtbMain.SelectAll();
rtbMain.SelectionColor = Color.Black;
rtbMain.SelectionBackColor = Color.White;
Regex regex = new(Pattern, RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(OriginalText);

if (matches.Count > 0)
{
    var rtbText = rtbMain.Text;
    var length = ShownText.Length;
    var allMatches = new List<Match>();

    for (int i = 0; i < matches.Count; i++)
    {
        var m = matches[i];
        allMatches.Add(m);
        Match nextMatch = null;
        if (matches.Count > i + 1)
        {
            nextMatch = matches[i + 1];
        }
        var sum = GetSum();
        var start = m.Index;
        var currentLength = m.Length;
        if (nextMatch != null)
        {
            var end = nextMatch.Index - start- sum;
            rtbMain.Select(start- 1, end);
        }
        else
        {
            var currentIndex = OriginalText.IndexOf(m.Value);
            rtbMain.Select(length - currentIndex, (length - currentIndex) - sum);
        }
        rtbMain.SelectionColor = GetColor(m.Value);
    }
    int GetSum()
    {
        return allMatches!.Select(m => m.Value.Length - 1).Sum();
    }
    Color GetColor(string color)
    {
        return Color.FromName(color);
    }
}
else
{
    Debug.WriteLine("No matches found");
}

由于 richtextbox 没有颜色标签,我不知道如何计算索引/长度的正确位置。

截屏:

提前致谢。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    您还可以匹配您正在解析的字符串的结束位置, 然后,在循环 Matches 集合时,您只需计算字符串内的当前位置,同时考虑每个匹配项的长度。

    通过稍微修改正则表达式,每个 Match 的 IndexLength 引用一个匹配的标签(例如,{green}),Group 1 中的每个值都是颜色的名称。

    是这样的:
    (请注意,这里仅使用了SelectionColor,因为我在每次迭代时都将一个新字符串附加到控件。添加的新字符串实际上已经是一个选择,因此无需显式设置选择的长度)

    string originalText = 
        "Hey, This{Red} IS A {Cyan}sample. The {Green}color is green color
    " +
        "plus other text {blue} and some more {orange}colors";
    
    string pattern = @"{(.*?)}|$";
    var matches = Regex.Matches(originalText, pattern, RegexOptions.IgnoreCase);
    int currentPos = 0;
    
    foreach (Match m in matches) {
        [richTextBox].AppendText(originalText.Substring(currentPos, m.Index - currentPos));
    
        currentPos = m.Index + m.Length;
        [richTextBox].SelectionColor = Color.FromName(m.Groups[1].Value);
    };
    [richTextBox].SelectionColor = [richTextBox].ForeColor;
    

    导致:

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 2011-08-06
      相关资源
      最近更新 更多