惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - KeithDan

Windows 8开发 WinRT 对ZIP文件解压缩及文件夹的ZIP压缩 wp应用发布,金宝贝点读 WP7游戏分裂细胞 WP7游戏方块夺宝 C#手工解析XML xeno tactic 2 完整版 Lua扫雷 惊人!天下奇闻“鹏” 今天很郁闷 HighLightCode1.2——开源项目 代码着色--开源系列 利用非托管dll实现多平台加密 非托管dll的需要注意的地方 page_load执行两次 transfer object (3) transfer object (2) transfer object (1) 中国象棋(网络版) 人生的阶梯
代码着色--关于循环与分组
KeithDan · 2008-04-23 · via 博客园 - KeithDan

本来这个功能应该算是编辑器的一个附属功能,本来有一个JS的代码着色器(syntaxhighlighter),现在版本是1.51,但是由于其功能始终是客户端的,有一些服务器操作比较麻烦,于是自己写了一个,当前只是实现了C#版本。
在这里,我讲述一下该代码实现模式,这里主要讲讲循环和分组的机制

主体:

HighLightCode:为高亮代码的基类,并抽象,含有抽象方法
通过方法实现实例

public static HighLightCode CreateHighLightCode(CodeType regexcodetype)
        
{
            HighLightCode code 
= null;
            
if (regexcodetype == CodeType.CSharp)
            
{
                code 
= new RegexCSharp();
            }


            
return code;
        }

RegexCSharp:实现HighLightCode方法。
当前为C#实现了该方法,如果Java类实现该方法,则可以扩展出Java的着色代码.

思路:
如果我们直接使用正则表达式进行匹配,那么比较麻烦,会出现一些问题,如://string abc = "hello";那么"hello"会被分析为引号部分,而非注释部分。要解决该问题,我们先分析一下代码着色的原理和基础。
特殊的符号包括单引号,双引号,单行注释,多行注释的判断,由于这些情况都是成对的出现,我们需要找出这4个情况前后匹配的数据进行分组处理。
注意,单行注释由//开头,\r\n结尾
如:string abc= "hello!";
那么string abc=作为group1,"hello!"作为group2,;作为group3。那么在group1和group3我们需要的仅仅是对关键字进行匹配,在这里最简单的方法就是正则表达式进行匹配和着色。那么对于group2无非就是添加深红色而已。但是对于分组我们需要找到最先出现的符号位置,如:string abc = "hello // world!";此时的//应该作为字符串而非注释,所以它必须为group2中。

分组方法:
我们先讨论只有一个目标符号的情况。即:string abc= "hello!";
我们首先将4个符号的出现的初始位置找到,进行排序,得到位置最小的符号,那么该组就是以该符号为基准。在这里,我使用了List进行排序。得到位置最小的符号组,那么它就是我们要寻找的目标符号,于是寻找他的结尾符号,则可以得到它具体的字符串。

List<RegexItem> regexs = new List<RegexItem>();
            RegexItem regx 
= null;

            
int count = 0;
            
int pos1 = code.IndexOf('"', start);
            
if (pos1 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos1;
                regx.RegexMode 
= Mode.DoubleQuotedString;
                regexs.Add(regx);
            }

            
int pos2 = code.IndexOf(BeginSingleLineComments, start);
            
if (pos2 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos2;
                regx.RegexMode 
= Mode.SingleLineComments;
                regexs.Add(regx);
            }

            
int pos3 = code.IndexOf(BeginMultiLineComments, start);
            
if (pos3 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos3;
                regx.RegexMode 
= Mode.MultiLineComments;
                regexs.Add(regx);
            }

            
int pos4 = code.IndexOf("'", start);
            
if (pos4 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos4;
                regx.RegexMode 
= Mode.SingleQuotedString;
                regexs.Add(regx);
            }

如上:pos1,pos2,pos3,pos4分别得到4个符号的最初位置,并放置于一个List<RegexItem>中,count表示查找到的符号的个数

if(找到了特殊符号)
{
   则将List排序,得到最小的符号
}

else
{
   则没有符号,所以都作为默认的数据处理
}

最后我们需要去匹配这些特殊符号,

if(该符号为双引号)
{
   找到双引号以前的位置数据
   
//这个就是group1
   
   找到后双引号位置
    找到双引号位置内的数据
   
//这个就是group2
   
}
。。。。。。

通过这样的逻辑判断就简单地分出一个代码片段的组,group1和group2

循环流程:
由于程序不会只有一个目标符号,如:
string a1= "hello!";
string a2= "i love you!";
//string "a3";
上面实例则存在7个组
group1=string a1=
group2="hello!"
group3=;
group4=string a2= 
group5="i love you!"
group6=;
group7=//string "a3";
 
这样的组会存在多个,于是我们从目标字符串的0位置开始到它的长度进行循环(for(int i=0;i<code.length;i++)),得到多个的目标组。

该图展示了查找的判断逻辑,每找到一个组,则实例出RegexItem,放置到List<RegexItem>集合中。

List<RegexItem> items = new List<RegexItem>();
        
private int CreateItem(string code, int start)
        
{
            List
<RegexItem> regexs = new List<RegexItem>();
            RegexItem regx 
= null;

            
int count = 0;
            
int pos1 = code.IndexOf('"', start);
            
if (pos1 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos1;
                regx.RegexMode 
= Mode.DoubleQuotedString;
                regexs.Add(regx);
            }

            
int pos2 = code.IndexOf(BeginSingleLineComments, start);
            
if (pos2 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos2;
                regx.RegexMode 
= Mode.SingleLineComments;
                regexs.Add(regx);
            }

            
int pos3 = code.IndexOf(BeginMultiLineComments, start);
            
if (pos3 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos3;
                regx.RegexMode 
= Mode.MultiLineComments;
                regexs.Add(regx);
            }

            
int pos4 = code.IndexOf("'", start);
            
if (pos4 > -1)
            
{
                count
++;
                regx 
= new RegexItem();
                regx.Postion 
= pos4;
                regx.RegexMode 
= Mode.SingleQuotedString;
                regexs.Add(regx);
            }

            RegexItem minItem 
= null;
            
if (count > 0)
            
{

                
if (regexs.Count > 1)
                
{
                    Comparison
<RegexItem> comp = new Comparison<RegexItem>(SortItmes);
                    regexs.Sort(comp);
                    minItem 
= regexs[0];
                }

                
else if (regexs.Count == 1)
                
{
                    minItem 
= regexs[0];
                }

            }

            
else
            
{
                minItem 
= new RegexItem();
                minItem.Postion 
= start;
                minItem.RegexMode 
= Mode.Default;
            }

            
int end = 0;


            RegexItem itemFirst 
= new RegexItem();
            itemFirst.RegexMode 
= Mode.Default;
            itemFirst.Postion 
= start;
            
if (minItem.RegexMode == Mode.DoubleQuotedString)
            
{
                end 
= code.IndexOf('"', minItem.Postion + 1);
                itemFirst.Text 
= code.Substring(start, minItem.Postion - start);
                items.Add(itemFirst);
                minItem.Text 
= code.Substring(minItem.Postion, end - minItem.Postion + 1);
                items.Add(minItem);
            }

            
else if (minItem.RegexMode == Mode.SingleLineComments)
            
{
                end 
= code.IndexOf(EndSingleLineComments, minItem.Postion + 1);
                
if (end == -1{ end = code.Length - 1; }//为最后一行
                else { end++; }//因为\r\n占两个字节

                itemFirst.Text 
= code.Substring(start, minItem.Postion - start);
                items.Add(itemFirst);
                minItem.Text 
= code.Substring(minItem.Postion, end - minItem.Postion + 1);
                items.Add(minItem);
            }

            
else if (minItem.RegexMode == Mode.MultiLineComments)
            
{
                end 
= code.IndexOf(EndMultiLineComments, minItem.Postion + 1);
                itemFirst.Text 
= code.Substring(start, minItem.Postion - start);
                items.Add(itemFirst);
                minItem.Text 
= code.Substring(minItem.Postion, end - minItem.Postion + 1);
                items.Add(minItem);
            }

            
else if (minItem.RegexMode == Mode.SingleQuotedString)
            
{
                end 
= code.IndexOf("'", minItem.Postion + 1);
                itemFirst.Text 
= code.Substring(start, minItem.Postion - start);
                items.Add(itemFirst);
                minItem.Text 
= code.Substring(minItem.Postion, end - minItem.Postion + 1);
                items.Add(minItem);
            }

            
else
            
{
                
// end = code.IndexOf(start, minItem.Postion - start + 1);
                end = code.Length - 1;
                minItem.Text 
= code.Substring(start, code.Length - start);
                items.Add(minItem);
            }


            
return end;
        }

public string GetHighLightCode(string code)
        
{
            
int i = 0;
            
//循环判断逻辑
            for (; i < code.Length; i++)
            
{
                
int start = CreateItem(code, i);
                i 
= start;
            }

            
        }


当然,如果没有源码的朋友可以到
http://www.cnblogs.com/KeithDan/archive/2008/04/23/1168279.html 去下载