【问题标题】:Why can't I change the color of repeated words in a RichTextBox?为什么我不能更改 RichTextBox 中重复单词的颜色?
【发布时间】:2019-05-09 20:53:02
【问题描述】:

我的程序必须在 RichTextBox 中找到特定的单词并更改它们的颜色(简单的语法高亮显示)。我正在使用Regex 来查找单词。
我能找到它们,但如果我的文本包含 2 个或更多相同的单词,我只能更改第一个的颜色,其他的保持不变。

Dim words As String = "(in|handles|object|sub|private|dim|as|then|if|regex)"
Dim rex As New Regex(words)
Dim mc As MatchCollection = rex.Matches(RichTextBox1.Text.ToLower)

Dim lower_case_text As String = RichTextBox1.Text.ToLower
For Each m As Match In mc
    For Each c As Capture In m.Captures
        MsgBox(c.Value)
        Dim index As Integer = lower_case_text.IndexOf(c.Value)
        Dim lenght As Integer = c.Value.Length

        RichTextBox1.Select(index, lenght)
        RichTextBox1.SelectionColor = Color.Blue
    Next
Next

我的代码需要通过单击按钮运行。我认为我的问题出在for each 循环中,但我不确定。
我已经有几个版本了,但都没有。

【问题讨论】:

    标签: regex vb.net winforms richtextbox


    【解决方案1】:

    这个方法可以用一些RegexOptions来简化

    RegexOptions.Compiled Or RegexOptions.IgnoreCase
    

    RegexOptions.Compiled
    如果文本很长(更快的执行以较慢的启动为代价),则可能很有用。

    RegexOptions.IgnoreCase
    执行不区分大小写的匹配。您无需转换 ToLower() 文本。

    RegexOptions.CultureInvariant
    必要时可以添加。

    有关详细信息,请参阅Regular Expression Options 文档。
    此外,请参阅Regex.Escape() 方法,如果部分模式可能包含一些元字符。

    您的代码可以简化为:

    Dim pattern As String = "in|handles|object|sub|private|dim|as|then|if|regex"
    Dim regx As New Regex(pattern, RegexOptions.Compiled Or RegexOptions.IgnoreCase)
    Dim matches As MatchCollection = regx.Matches(RichTextBox1.Text)
    
    For Each match As Match In matches
        RichTextBox1.Select(match.Index, match.Length)
        RichTextBox1.SelectionColor = Color.Blue
    Next
    

    【讨论】:

    • 感谢您的回答和良好的解释,就像一个魅力。
    【解决方案2】:

    我认为这是因为 lower_case_text.IndexOf(c.Value) 仅在字符串中找到索引第一个匹配项。

    一个快速的技巧是在每个循环中更改lower_case_text

    如:“使某物变暗”

    找到第一个暗淡后,将其替换为相同长度的内容,例如“000”

    所以你的lower_case_text 现在将是:“000 something dim something”

    然后您将能够获得第二个“dim”的有效索引

    这不是一个优雅的解决方案,但应该可以。

    希望有降神会。

    【讨论】:

      【解决方案3】:

      首先,不需要使用Captures 集合(以及括号),因为Capture 将与Match 保持相同的值。其次,您可以在正则表达式模式的开头使用内联正则表达式选项(例如(?i) - 设置不区分大小写的搜索)。内联选项的优点是您可以在模式的任何部分设置和取消它们(例如(?-i) - 取消不区分大小写的搜索)。

      Dim input = 
         "If i = 10 Then
              i = 0
          Else
              i = 5
          End If"
      Dim pattern = "(?i)in|handles|object|sub|private|dim|as|then|else|end|if|regex"
      Dim mc = Regex.Matches(input, pattern)
      For Each m As Match In mc
          Dim index = m.Index
          Dim length = m.Length
      Next
      

      【讨论】:

      • 谢谢你的回答,虽然我已经接受了,你的也很有帮助。
      猜你喜欢
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 2013-02-08
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 2011-02-01
      相关资源
      最近更新 更多