本文介绍了不寻常的语法突出问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我花了很多时间用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 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上找到: n-Scripting的SMO教程3 [ ^ ] 请注意换行符被临时字符串中的空格替换以进行搜索,因为换行符对于正则表达式搜索是有问题的。 /// < 摘要 > /// 富文本框的语法着色。 /// < / summary > /// < param 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 ,新 字符串(){ 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( 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)= 之前结束 功能 < 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 + 25) ( or )6) Any number 0-9This 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|boolean3) One of the quotes has its colour completely offset4) 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 SubWhat 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 SubWhat 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()) NextI 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.CompilerServicesModule 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 FunctionEnd Module 这篇关于不寻常的语法突出问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
05-27 20:59
查看更多