不寻常的语法突出问题 [英] Unusual syntax highlighting issue

查看:86
本文介绍了不寻常的语法突出问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我花了很多时间用Regex编写语法荧光笔。



这些是允许的匹配:



1)String | int | boolean然后是一个空格(用于变量声明,例如String myString)

2)FilterableList< String | int | boolean>

3)打开括号,无论是什么或者(某事物都是空格)引用(无论是什么都没有,或者是什么空间)关闭括号,例如。 (myString +你好)

4)一个空格,然后+ | - | * | / | == |&&或||然后是一个空间,例如。 1 + 2

5)(或)

6)任意数字0-9



这几乎可行完美但有一些问题。请参阅正则表达式语法荧光笔 - Imgur专辑 [ ^ ]



1)整个报价,包括''应为黄色。

2)FilterableList<>应该是蓝色的,如果int | String | boolean

3里面的内容应该是绿色的)其中一个引号的颜色完全偏移

4)The)不是红色的。



似乎某些比赛干扰他人,任何想法如何克服这个?

 私有  Sub  updateCodeSyntaxHighlighting()
allowCodeInput = False

Dim 前缀正如 字符串 = (?< ;返回>中
Dim 后缀作为 String = )(。*)?(?!。)

Dim listMatches 作为 正则表达式(前缀& FilterableList<。*>&后缀)
Dim variableMatches 作为 正则表达式(前缀& (int | String | boolean)|<(?< return> int | String | boolean)>& suffix)
Dim quoteMatches As 正则表达式( \((。*)? & prefix& 。*)(。*)?\)
Dim symbolMatches 作为 正则表达式(前缀& (([[+ \ - / *] | == |&& | \ | \ |))| \(| \) )
Dim numberMatches As 正则表达式(前缀& [0-9])

Dim selPos As Integer = codeEditorBox.SelectionStart
< span class =code-keyword> Dim selPos2 As Integer = codeEditorBox.GetFirstCharIndexOfCurrentLine

如果 codeEditorBox.Text = 然后
codeEditorBox。选择 0 ,codeEditorBox.Lines(codeEditorBox.GetLineFromCharIndex(selPos))。Length)
codeEditorBox.SelectionStart = selPos2
codeEditorBox.SelectionColor = codeEditorBox.ForeColor
codeEditorBox.Sele ctionStart = selPos
结束 如果

对于 每个匹配作为匹配 listMatches.Matches(codeEditorBox.Text)
高亮显示(匹配,selPos,Color.FromArgb( 64 255 255 ))
下一步

对于 每个匹配 As 匹配 variableMatches.Matches(codeEditorBox.Text)
高亮显示(匹配,selPos,Color.FromArgb( 64) 255 64 ))
下一步

对于 每个匹配作为匹配 quoteMatches.Matches(codeEditorBox.Text)
高亮显示(匹配,selPos,Color.FromArgb( 255 255 64 ))
下一步

对于 每个匹配 As 匹配 symbolMatches.Matches(codeEditorBox.Text)
highlight(match,selPos,Color.FromArgb( 255 64 64 ))
下一步

对于 每个匹配作为匹配 numberMatches.Matches(codeEditorBox.Text)
高亮显示(匹配,selPos,Color.FromArgb( 50 155 155 ))
下一步

codeEditorBox.SelectionLength = 0

allowCodeInput = True
结束 Sub

私有 Sub 高亮显示(匹配作为匹配,selPos 作为 整数,c 作为颜色)
Dim index As 整数 = matc h.Index
Dim length As Integer = match.Result( $ {return})。长度

codeEditorBox。选择(索引,长度)
codeEditorBox.SelectionColor = c
codeEditorBox.SelectionStart = index + length
codeEditorBox .SelectionColor = codeEditorBox.ForeColor
codeEditorBox.SelectionStart = selPos
End Sub





我尝试过:



多个正则表达式生成器

-------------------------

解决方案

{return})。长度

codeEditorBox。选择(索引,长度)
codeEditorBox。 SelectionColor = c
codeEditorBox.SelectionStart = index + length
codeEditorBox.SelectionColor = codeEditorBox.ForeColor
codeEditorBox.SelectionStart = selPos
End Sub





我尝试过:



多个正则表达式生成器

-------------------------


我曾经在C#中为SQL代码做了类似的事情,也许这对你有用。

完整的源代码可以在CodeProject上找到:< a href =https://www.codeproject.com/script/Articles/ListAlternatives.aspx?aid=162684> n-Scripting的SMO教程3 [ ^ ]

请注意换行符被临时字符串中的空格替换以进行搜索,因为换行符对于正则表达式搜索是有问题的。

  ///   <  摘要 >  
/// 富文本框的语法着色。
/// < / summary >
/// < param < span class =code-summarycomment> name =colorComments > 还有颜色注释绿色。< / param >
private void SyntaxColoring( bool colorComments)
{
this .richTextScript.Focus();
this .richTextScript.SelectionStart = 0 ;
this .richTextScript.SelectionLength = 0 ;
string richText = this .richTextScript.Text.Replace( \ n );

// 检查关键字并应用蓝色。
foreach var 关键字 .Keywords)
{
var reg = Regex.Matches(richText, @ ([,() - ]) + keyword + @ ([,() - ]));

foreach (匹配匹配 in reg)
{
this .richTextScript.SelectionStart = match.Index;
this .richTextScript.SelectionLength = match.Length;
this .richTextScript.SelectionColor = Color.Blue;
this .richTextScript.SelectionFont = new 字体( Courier New 10 ,FontStyle.Regular);
}
}

// 查找字符串并应用红色。
foreach (匹配 Regex.Matches(richText, @ ([])(?:(?=(\\?))\ 2.) *?\1))
{
this .richTextScript.SelectionStart = match.Index;
this .richTextScript.SelectionLength = match.Length;
this .richTextScript.SelectionColor = Color.IndianRed;
this .richTextScript.SelectionFont = new 字体( Courier New 10 ,FontStyle.Regular);
}

// 检查注释并应用绿色。
if (colorComments)
{
foreach (匹配匹配 Regex.Matches(richText, @ / \ *。*?\ * /))
{
this .richTextScript.SelectionStart = match.Index;
this .richTextScript.SelectionLength = match.Length;
this .richTextScript.SelectionColor = Color.Green;
this .richTextScript.SelectionFont = new 字体( Courier New 10 ,FontStyle.Regular);
}
}
}


解决了!我最终使用了正则表达式和良好的旧编程逻辑的组合。



问题是我为不同字符串着色的顺序。如果为richtextbox的不同部分着色,使SelectionStart不大于最后一个部分,则某些部分会失去颜色。这让我很困惑 - 因为某些部分没有颜色,我认为正则表达式没有正确捕获东西。



为了解决订购问题,我存储了索引和一个SyntaxHighlightOperation,在SortedDictionary中保存我的高亮功能的其他必要值。这有效地按索引对突出显示操作进行了排序,完全解决了着色问题。



结果如下: [ ^ ]



这里是最终代码:

  Dim  operations  As   SortedDictionary( of   Integer ,SyntaxHighlightOperation)

Dim 代码正如 字符串 = codeEditorBox.Text

Dim 任何作为 字符串 = [\(\);]
Dim codeElements As String = 服务器|文件
Dim variableTypes 作为 字符串 = string | int | bool | dec
Dim 枚举 As 字符串 = SyntaxRating | Mood

对于 每个匹配作为匹配 正则表达式(任何).Matches(code)
operations.Add(match.Index, SyntaxHighlightOperation(match.Index, 1 ,selPos,SyntaxColours.Symbol))
下一步

对于 每个匹配 As 匹配 正则表达式(variableTypes).Matches(code)
如果 code.hasAnyAround(match.Value,match.Index, New 字符串()(){
字符串 (){ },
字符串(){ }
})然后
operations.Add(match.Index - 1 SyntaxHighlightOperation(match.Index - 1 ,match.Value.Length + 2 ,selPos,SyntaxColours.Variable))
ElseIf code.hasAround(match.Value,match.Index , 字符串(){ < span class =code-string> List<, >} )和此外 code.hasAround(match.Value,match.Index, New String (){ < >})然后
operations.Add(match.Index - 5 SyntaxHighlightOperation(match.Index - 5 ,match.Value .Length + 2 ,selPos,SyntaxColours.List))
operations.Add(match.Index, New SyntaxHighlightOperation(match.Index,match.Value.Length,selPos,SyntaxColours.Variable))
operations.Add(match.Index + match.Value.Length, SyntaxHighlightOperation(match.Index + match.Value.Length, 1 ,selPos,SyntaxC olours.List))
结束 如果
下一步

对于 每个匹配作为匹配 正则表达式(codeElements).Matches(代码)
operations.Add(match.Index, SyntaxHighlightOperation(match.Index,match.Value.Length,selPos,SyntaxColours.CodeElement))
下一步

对于 每个匹配作为匹配 Regex(枚举).Matches(code)
如果 code.hasAfter(match.Value,match.Index, 然后
操作。添加(match.Index, SyntaxHighlightOperation(match.Index,match.Value.Length,selPos,SyntaxColours.Enumeration))
结束 如果
下一步

''' ''''''''''''''' '''''''''

对于 每个 operation As SyntaxHighlightOperation In operations.Values
highlight(operation.getIndex(),operation。 getLength(),operation.getSelPos(),operation.getColor())
下一步





我也做了扩展class,以帮助在匹配之前,之后或之前和之后需要某些字符串的逻辑:



  Imports  System.Runtime.CompilerServices 

Module ExtensionMethods

< Extension( )>
公开 功能 hasAround(code As 字符串,text 作为 字符串, index 作为 整数,around()作为 字符串作为 布尔
Dim As String = around(< span class =code-digit> 0 )
Dim As 字符串 = around( 1

如果 index - before.Length< 0 OrElse index + text.Length = code.Length Then 返回 错误

返回 code.Substring(index - before.Length,before .Length)=之前 AndAlso code.Substring(index + text.Length,after。长度)=
之后结束 功能

<扩展( )>
公共 功能 hasAnyAround(code As 字符串,text 作为 字符串, index 作为 整数,around()() As 字符串作为 布尔
对于 每个 a As 字符串()
附近 Dim 之前 字符串 = a( 0 )在$ span class =co。之后
Dim 解除关键字>作为 字符串 = a( 1

如果 index - before.Length< 0 OrElse index + text.Length> = code.Length 然后 返回 错误
如果 code.Substring(index - before.Length,before.Length)=之前 AndAlso code.Substring(index + text.Length,after.Length) = 然后 返回 True
下一步

返回 False
结束 功能

<扩展( )>
公共 功能 hasBefore(代码 As 字符串,text 作为 字符串, index 作为 整数,在 As 字符串)作为 布尔
如果 index - before.Length< 0 然后 返回 False
返回 code.Substring(index - before.Length,before.Length)=
之前< span class =code-keyword>结束 功能

< Extension()>
公共 功能 hasAfter(代码 As 字符串,text 作为 字符串, index 作为 整数,在 As 字符串)作为 布尔
如果 index + text.Length> = code.Length 然后 返回 False
返回 code.Substring(index + text.Length,after。长度)=
之后结束 功能

结束 模块


Hi,

I've spent quite some time writing a syntax highlighter using Regex.

These are the permitted matches:

1) String|int|boolean and then a space (for variable declaration eg. String myString)
2) FilterableList<String|int|boolean>
3) open bracket, either nothing or (something then a space) "a quote" (either nothing or a space then something) close bracket eg. (myString + "hello")
4) A space, then +|-|*|/|==|&& or || and then a space eg. 1 + 2
5) ( or )
6) Any number 0-9

This almost works perfectly but there are a few issues. See Regex Syntax Highlighter - Album on Imgur[^]

1) The entire quote, including '"' should be yellow.
2) FilterableList<> should be blue, what's inside should be green if int|String|boolean
3) One of the quotes has its colour completely offset
4) The ) isn't red.

It seems to be the case that certain matches interfere with others, any ideas how to overcome this?

Private Sub updateCodeSyntaxHighlighting()
        allowCodeInput = False

        Dim prefix As String = "(?<return>"
        Dim suffix As String = ")( .*)?(?!.)"

        Dim listMatches As New Regex(prefix & "FilterableList<.*>" & suffix)
        Dim variableMatches As New Regex(prefix & "(int|String|boolean)|<(?<return>int|String|boolean)>" & suffix)
        Dim quoteMatches As New Regex("\((.* )?" & prefix & """.*"")( .*)?\)")
        Dim symbolMatches As New Regex(prefix & "( ([+\-/*]|==|&&|\|\|) )|\(|\))")
        Dim numberMatches As New Regex(prefix & "[0-9])")

        Dim selPos As Integer = codeEditorBox.SelectionStart
        Dim selPos2 As Integer = codeEditorBox.GetFirstCharIndexOfCurrentLine

        If Not codeEditorBox.Text = "" Then
            codeEditorBox.Select(0, codeEditorBox.Lines(codeEditorBox.GetLineFromCharIndex(selPos)).Length)
            codeEditorBox.SelectionStart = selPos2
            codeEditorBox.SelectionColor = codeEditorBox.ForeColor
            codeEditorBox.SelectionStart = selPos
        End If

        For Each match As Match In listMatches.Matches(codeEditorBox.Text)
            highlight(match, selPos, Color.FromArgb(64, 255, 255))
        Next

        For Each match As Match In variableMatches.Matches(codeEditorBox.Text)
            highlight(match, selPos, Color.FromArgb(64, 255, 64))
        Next

        For Each match As Match In quoteMatches.Matches(codeEditorBox.Text)
            highlight(match, selPos, Color.FromArgb(255, 255, 64))
        Next

        For Each match As Match In symbolMatches.Matches(codeEditorBox.Text)
            highlight(match, selPos, Color.FromArgb(255, 64, 64))
        Next

        For Each match As Match In numberMatches.Matches(codeEditorBox.Text)
            highlight(match, selPos, Color.FromArgb(50, 155, 155))
        Next

        codeEditorBox.SelectionLength = 0

        allowCodeInput = True
    End Sub

    Private Sub highlight(match As Match, selPos As Integer, c As Color)
        Dim index As Integer = match.Index
        Dim length As Integer = match.Result("${return}").Length

        codeEditorBox.Select(index, length)
        codeEditorBox.SelectionColor = c
        codeEditorBox.SelectionStart = index + length
        codeEditorBox.SelectionColor = codeEditorBox.ForeColor
        codeEditorBox.SelectionStart = selPos
    End Sub



What I have tried:

Multiple regex generators
-------------------------

解决方案

{return}").Length codeEditorBox.Select(index, length) codeEditorBox.SelectionColor = c codeEditorBox.SelectionStart = index + length codeEditorBox.SelectionColor = codeEditorBox.ForeColor codeEditorBox.SelectionStart = selPos End Sub



What I have tried:

Multiple regex generators
-------------------------


I once did something like this in C# for SQL code, maybe this will be of use to you.
The full source code can be found on CodeProject: SMO Tutorial 3 of n - Scripting[^]
Note that newlines are replaced by spaces in the temporary string for searching, as newlines are problematic for regex searches.

/// <summary>
/// Syntax coloring for rich text box.
/// </summary>
/// <param name="colorComments">Also color comments green.</param>
private void SyntaxColoring(bool colorComments)
{
    this.richTextScript.Focus();
    this.richTextScript.SelectionStart = 0;
    this.richTextScript.SelectionLength = 0;
    string richText = this.richTextScript.Text.Replace("\n", " ");

    // Check for keywords and apply blue color.
    foreach (var keyword in this.Keywords)
    {
        var reg = Regex.Matches(richText, @"([ ,()-])" + keyword + @"([ ,()-])");

        foreach (Match match in reg)
        {
            this.richTextScript.SelectionStart = match.Index;
            this.richTextScript.SelectionLength = match.Length;
            this.richTextScript.SelectionColor = Color.Blue;
            this.richTextScript.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        }
    }

    // Find strings and apply red color.
    foreach (Match match in Regex.Matches(richText, @"([""'])(?:(?=(\\?))\2.)*?\1"))
    {
        this.richTextScript.SelectionStart = match.Index;
        this.richTextScript.SelectionLength = match.Length;
        this.richTextScript.SelectionColor = Color.IndianRed;
        this.richTextScript.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
    }

    // Check for comments and apply green color.
    if (colorComments)
    {
        foreach (Match match in Regex.Matches(richText, @"/\*.*?\*/"))
        {
            this.richTextScript.SelectionStart = match.Index;
            this.richTextScript.SelectionLength = match.Length;
            this.richTextScript.SelectionColor = Color.Green;
            this.richTextScript.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        }
    }
}


Solved! I ended up using a combination of Regex and good old programming logic.

The issue was the order in which I was colouring the different strings. If you colour different parts of a richtextbox in such a way that SelectionStart is not greater than the last, some parts lose their colour. That's what confused me - as there was no colour on certain parts I assumed the Regex hadn't captured things correctly.

To fix the ordering issue I stored the index and a SyntaxHighlightOperation holding the other necessary values for my highlight function in a SortedDictionary. That effectively sorted the highlighting operations by index, completely resolving the colouring issue.

Here's the result: [^]

And here's the final code:

Dim operations As New SortedDictionary(Of Integer, SyntaxHighlightOperation)

        Dim code As String = codeEditorBox.Text

        Dim anything As String = "[\(\);]"
        Dim codeElements As String = "Server|Files"
        Dim variableTypes As String = "string|int|bool|dec"
        Dim enumerations As String = "SyntaxRating|Mood"

        For Each match As Match In New Regex(anything).Matches(code)
            operations.Add(match.Index, New SyntaxHighlightOperation(match.Index, 1, selPos, SyntaxColours.Symbol))
        Next

        For Each match As Match In New Regex(variableTypes).Matches(code)
            If code.hasAnyAround(match.Value, match.Index, New String()() {
                                 New String() {"""", """"},
                                 New String() {"(", ")"}
                                 }) Then
                operations.Add(match.Index - 1, New SyntaxHighlightOperation(match.Index - 1, match.Value.Length + 2, selPos, SyntaxColours.Variable))
            ElseIf code.hasAround(match.Value, match.Index, New String() {"List<", ">"}) AndAlso code.hasAround(match.Value, match.Index, New String() {"<", ">"}) Then
                operations.Add(match.Index - 5, New SyntaxHighlightOperation(match.Index - 5, match.Value.Length + 2, selPos, SyntaxColours.List))
                operations.Add(match.Index, New SyntaxHighlightOperation(match.Index, match.Value.Length, selPos, SyntaxColours.Variable))
                operations.Add(match.Index + match.Value.Length, New SyntaxHighlightOperation(match.Index + match.Value.Length, 1, selPos, SyntaxColours.List))
            End If
        Next

        For Each match As Match In New Regex(codeElements).Matches(code)
            operations.Add(match.Index, New SyntaxHighlightOperation(match.Index, match.Value.Length, selPos, SyntaxColours.CodeElement))
        Next

        For Each match As Match In New Regex(enumerations).Matches(code)
            If code.hasAfter(match.Value, match.Index, ".") Then
                operations.Add(match.Index, New SyntaxHighlightOperation(match.Index, match.Value.Length, selPos, SyntaxColours.Enumeration))
            End If
        Next

        ''''''''''''''''''''''''''''''''''

        For Each operation As SyntaxHighlightOperation In operations.Values
            highlight(operation.getIndex(), operation.getLength(), operation.getSelPos(), operation.getColor())
        Next



I also made an extensions class to help with the logic for requiring certain strings before, after or before and after the match:

Imports System.Runtime.CompilerServices

Module ExtensionMethods

    <Extension()>
    Public Function hasAround(code As String, text As String, index As Integer, around() As String) As Boolean
        Dim before As String = around(0)
        Dim after As String = around(1)

        If index - before.Length < 0 OrElse index + text.Length = code.Length Then Return False

        Return code.Substring(index - before.Length, before.Length) = before AndAlso code.Substring(index + text.Length, after.Length) = after
    End Function

    <Extension()>
    Public Function hasAnyAround(code As String, text As String, index As Integer, around()() As String) As Boolean
        For Each a As String() In around
            Dim before As String = a(0)
            Dim after As String = a(1)

            If index - before.Length < 0 OrElse index + text.Length >= code.Length Then Return False
            If code.Substring(index - before.Length, before.Length) = before AndAlso code.Substring(index + text.Length, after.Length) = after Then Return True
        Next

        Return False
    End Function

    <Extension()>
    Public Function hasBefore(code As String, text As String, index As Integer, before As String) As Boolean
        If index - before.Length < 0 Then Return False
        Return code.Substring(index - before.Length, before.Length) = before
    End Function

    <Extension()>
    Public Function hasAfter(code As String, text As String, index As Integer, after As String) As Boolean
        If index + text.Length >= code.Length Then Return False
        Return code.Substring(index + text.Length, after.Length) = after
    End Function

End Module


这篇关于不寻常的语法突出问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆