玩程序 之 一 . 字符串处理工具(可通过C#脚本扩展)

平常喜欢写点小东西玩玩,既可以娱乐自己满足自己的虚荣心,又可以方便工作和学习,今天且拿出一个来,与大家一起分享!

 1. 软件介绍

言归正传,先看看需求,有这样一串字符串 abc,def,ghi,jkl,mno 我想把它转为

<td>abc</td><td>def</td><td>ghi</td><td>jkl</td><td>mno</td>

也许这很简单,因为毕竟只有几条而已,但是如果这句话有上百个单元呢,我想大部分程序员应该和我一样,写个小程序来帮我们实现这个功能,那问题来了,挖掘机技……(好吧,习惯了),如果我现在要把上面那句转为 abc|def|ghi|jkl|mno 又当如何,再写一个程序? No!

先看看我是怎么做的:

 首先请无视工具栏那几个按钮,没啥作用(后面会提到),左侧两个文本框,上面的是输入,下面的是输出,右侧,是程序的核心部分,一个命令输入文本框(类似于DOS窗口)(本人开发的吆^_^),带有自动提示(是我Kiang来的),也许会有人问我,为啥做成命令行的,呵呵,装逼不需要解释。

这里面实现了几中常见字符串处理的方式,但是你以为这就完了吗,然而并没有,哥这个是带有脚本功能的,也就是说,这个不起眼的程序是可以通过脚本来扩展的。

2. 脚本扩展

  该程序使用了CSScript  (英文的,别急着点,看完这篇先),CSScript 是(奉上我渣渣的中文翻译)

  CS-Script (读作 C sharp script) 使用ECMA标准的C#作为编程语言并基于 CLR (Common Language Runtime) 的脚本系统 . CS-Script 目前支持 Windows 和 Linux 的 CLR (MS .NET4.0 and Mono).  

简单来说就是通过.Net程序动态加载CS-Script,使用方式和C/C++ 调用的Lua等语言的方式一样,当然我是猜的,我也不清楚,这里先看看CS-Script的使用方式,

首先引用程序集

  

  接下这一步是非必要的,可以根据自己的需要来调整。在这里我们要定义脚本所要继承的类和要实现的接口,:

  代码分别如下:

  BaseCommand.cs 文件

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Drawing;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Windows.Forms;
 7 namespace StringTools
 8 {
 9     /// <summary>
10     /// 脚本所要集成的父类,提供一些基本方法
11     /// </summary>
12     public class BaseCommand
13     {
14 
15         /// <summary>
16         /// 窗体主体,方便在以后开发中可以通过脚本方式直接调用窗体控件,如上面没实现任何功能的按钮
17         /// </summary>
18         public FrmMain CurrMainForm { get; set; }
19         /// <summary>
20         /// 用于记忆当前命令行控件的字体颜色
21         /// </summary>
22         public Color DefaultColor { get; set; }
23         /// <summary>
24         /// 命令行字典
25         /// </summary>
26         public Dictionary<string, string> CommandList { get; set; }
27 
28         /// <summary>
29         /// 向输出文本框写入文本
30         /// </summary>
31         /// <param name="message"></param>
32         public virtual void Print(string message)
33         {
34             CurrMainForm.txtOutput.Text = message;
35             CurrMainForm.txtCon.Write();
36         }
37 
38         /// <summary>
39         /// 清理命令行控件内容
40         /// </summary>
41         public void ClearCommand()
42         {
43             CurrMainForm.txtCon.Clear();
44         }
45 
46         /// <summary>
47         /// 向命令行控件写信息
48         /// </summary>
49         /// <param name="msg"></param>
50         public virtual void WriteCommand(string msg = "")
51         {
52             CurrMainForm.txtCon.Write(msg);
53         }
54 
55         /// <summary>
56         /// 向命令行控件写信息,并带有字体颜色
57         /// </summary>
58         /// <param name="msg"></param>
59         /// <param name="fontColor"></param>
60         public virtual void WriteCommand(string msg, Color fontColor)
61         {
62             CurrMainForm.txtCon.SelectionColor = fontColor;
63             CurrMainForm.txtCon.Write(msg);
64             CurrMainForm.txtCon.SelectionColor = DefaultColor;
65         }
66 
67         /// <summary>
68         /// 初始化5个按钮的单击事件
69         /// </summary>
70         internal void IniteBtn()
71         {
72             CurrMainForm.btnNo1.Click += OnbtnNo_Click;
73             CurrMainForm.btnNo2.Click += OnbtnNo_Click;
74             CurrMainForm.btnNo3.Click += OnbtnNo_Click;
75             CurrMainForm.btnNo4.Click += OnbtnNo_Click;
76             CurrMainForm.btnNo5.Click += OnbtnNo_Click;
77         }
78         /// <summary>
79         /// 单击事件方法
80         /// </summary>
81         /// <param name="sender"></param>
82         /// <param name="e"></param>
83         private void OnbtnNo_Click(object sender, EventArgs e)
84         {
85             BtnClick(int.Parse((sender as ToolStripButton).Tag.ToString()));
86         }
87         /// <summary>
88         /// 可重载方法,方便脚本中处理对应的事件方法
89         /// </summary>
90         /// <param name="index"></param>
91         public virtual void BtnClick(int index)
92         {
93 
94         }
95     }
96 }
View Code

  ICommand.cs 文件

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Drawing;
 4 using System.Linq;
 5 using System.Text;
 6 
 7 namespace StringTools
 8 {
 9     /// <summary>
10     /// 脚本所要是现实的接口
11     /// </summary>
12     public interface ICommand
13     {
14         /// <summary>
15         /// 命令执行方法
16         /// </summary>
17         /// <param name="cmd"></param>
18         /// <param name="inputText"></param>
19         void Exec(string cmd, string inputText);
20         /// <summary>
21         /// 帮助文档方法
22         /// </summary>
23         /// <returns></returns>
24         string HelpDoc();
25         /// <summary>
26         /// 命令列表,继承 BaseCommand 后默认实现
27         /// </summary>
28         Dictionary<string, string> CommandList { get; }
29         /// <summary>
30         /// 主界面 ,继承 BaseCommand 后默认实现(脚本设置无效)
31         /// </summary>
32         FrmMain CurrMainForm { get; set; }
33         /// <summary>
34         /// 命令行默认字体颜色,继承 BaseCommand 后默认实现(脚本设置无效)
35         /// </summary>
36         Color DefaultColor { get; set; }
37     }
38 }
View Code

 当定义完毕之后就可以开始写脚本代码了

  

  ExecScript.cs 是今天这篇文档的主角,而StringExtension.cs是一些对string类型的扩展方法实现的文件

 在开始介绍之前,先对CS-Script指令做一点介绍,

  • //css_import      --引入一个脚本文件(*.cs)
  • //css_reference  --引入程序集文件(*.dll)
  • //css_prescript and //css_postscript  
  • //css_resource   --引入资源文件
  • //css_args        -- 参数 如果脚本中有Main放,可以用
  • //css_searchdir 
  • //css_ignore_namespace
  • //css_precompiler
  • //css_nuget

 这些指令要放在脚本文件的前面(类似于注释一样),好接下来就是ExecScript.cs文件的内容了

  1 //css_import StringExtension.cs
  2 
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Text.RegularExpressions;
  9 using System.Windows.Forms;
 10 namespace StringTools
 11 {
 12     public class ExecScript : BaseCommand, ICommand
 13     {
 14         public ExecScript()
 15         {
 16             BuildList();
 17         }
 18         
 19         Random rand=new Random (DateTime.Now.Millisecond);
 20 
 21         //生成命令列表,用于自动提示
 22         private void BuildList()
 23         {
 24             CommandList = new Dictionary<string, string>();
 25             CommandList.Add("rep", "rep [1] [2]
   -- 字符串替换,[1] 目标,[2] 替换内容");
 26             CommandList.Add("repregx", "repregx [1] [2]
   -- 字符串替换,[1] 正则表达式 ,[2] 替换内容");
 27             CommandList.Add("idx", "idx [1]
   -- 顺序查找字符位置,[1] 字符");
 28             CommandList.Add("ldx", "ldx [1]
   -- 逆序查找字符位置,[1] 字符");
 29             CommandList.Add("len", "len
   -- 字符串长度");
 30             CommandList.Add("spl", "spl [1]
   -- 字符串按指定字符分为行,[1]字符 ");
 31             CommandList.Add("spe", "spe [1] [2] [3] [4]
   -- 字符串替换扩展,[1] 目标,[2] 左侧 [3] 右侧 [4] 替换内容");
 32             CommandList.Add("sbr", "sbr
   -- 字符串封装StringBuilder");
 33             CommandList.Add("regex", "regex [1]
   -- 正则表达式匹配");
 34             CommandList.Add("popo", "popo
   -- 这都是泡沫");            
 35 
 36             CommandList.Add("print", "print [1]
   -- 向输出打印数据");
 37             CommandList.Add("cls", "cls
   -- 清理命令区域内容");
 38             CommandList.Add("?", "?
   -- 帮助 同 “help”");
 39             CommandList.Add("help", "help
   -- 帮助 同 “?”");
 40             CommandList.Add("cmdlst", "cmdlst
   -- 列出当前可用的命令");
 41             CommandList.Add("ver", "ver
   -- 获取脚本版本");
 42         }
 43 
 44 
 45         //命令执行入口
 46         public void Exec(string cmd, string inptuText)
 47         {
 48             if (string.IsNullOrEmpty(cmd))
 49             {
 50                 WriteCommand();
 51                 return;
 52             }
 53 
 54             string[] arr = cmd.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
 55 
 56             if (arr[0] != "regex")
 57             {
 58                 for (int i = 1; i < arr.Length; i++)
 59                 {
 60                     if (arr[0] == "repregx" && i == 1)
 61                         continue;
 62                     arr[i] = arr[i].Replace("\s", " ").Replace("\t", "	")
 63                                    .Replace("\d", "").Replace("\n", "
")
 64                                    .Replace("\r", "
");
 65                 }
 66             }
 67 
 68             try
 69             {
 70                 switch (arr[0])
 71                 {
 72                     case "rep":
 73                         Print(inptuText.Replace(arr[1], arr[2]));
 74                         break;
 75                     case "idx":
 76                         Print(inptuText.IndexOf(arr[1]).ToString());
 77                         break;
 78                     case "ldx":
 79                         Print(inptuText.LastIndexOf(arr[1]).ToString());
 80                         break;
 81                     case "len":
 82                         Print(inptuText.Length.ToString());
 83                         break;
 84                     case "spl":
 85                         Print(inptuText.SplitForRow(new char[] { arr[1][0] }));
 86                         break;
 87                     case "spe":
 88                         Print(inptuText.SplitWithOp(arr[1].ToCharArray(), arr[2], arr[3], arr[4]));
 89                         break;
 90                     case "sbr":
 91                         Print(inptuText.ToStringBuilder());
 92                         break;
 93                     case "popo":
 94                         StringBuilder popSbr=new StringBuilder();
 95                         for (int pop1 = 0; pop1 < 1000; pop1++)
 96                         {
 97                             var popoRand=rand.Next(0,9);
 98                             switch (popoRand-1)
 99                             {
100                                 case 0:popSbr.Append(".");break;
101                                 case 1:popSbr.Append("");break;
102                                 case 2:popSbr.Append("o");break;
103                                 case 3:popSbr.Append("O");break;
104                                 case 4:popSbr.Append("0");break;
105                                 case 5:popSbr.Append("");break;
106                                 case 6:popSbr.Append("");break;
107                                 case 7:popSbr.Append("");break;
108                                 case 8:popSbr.Append("");break;
109                             }
110                             if (pop1 % 50 == 49)
111                             {
112                                 popSbr.AppendLine();
113                             }
114 
115                         }
116                         Print(popSbr.ToString());
117                         break;
118                     case "regex":
119                         var ms = Regex.Matches(inptuText, arr[1]);
120                         StringBuilder regxsbr = new StringBuilder();
121                         foreach (Match i in ms)
122                         {
123                             regxsbr.AppendLine("---------------------------");
124                             regxsbr.AppendFormat("{0}
", i.Value);
125                             foreach (Group j in i.Groups)
126                             {
127                                 regxsbr.AppendFormat("    {0}
", j.Value);
128                             }
129                         }
130 
131                         Print(regxsbr.ToString());
132                         break;
133                     case "repregx":
134 
135                         Print(Regex.Replace(inptuText, arr[1], arr[2]));
136                         break;
137 
138 
139                     case "cmdlst":
140                         StringBuilder cmdListStr = new StringBuilder();
141                         var cmdList=CommandList.Keys.ToArray();
142                         for (int i = 0; i <cmdList.Length; i++)
143                         {
144                             cmdListStr.Append(cmdList[i].PadRight(10, ' '));
145                             if (i%6 == 5)
146                             {
147                                 cmdListStr.AppendLine();
148                             }
149                         }
150                         WriteCommand(cmdListStr.ToString());
151                         break;
152                     case "print":
153                         Print(arr[1]);
154                         break;
155                     case "cls":
156                         ClearCommand();
157                         break;
158                     case "?":
159                     case "help":
160                         if (arr.Length == 2 && CommandList.Keys.Contains(arr[1]))
161                         {
162                             WriteCommand(CommandList[arr[1]]);
163                         }
164                         else
165                         {
166                             WriteCommand(HelpDoc());
167                         }
168                         break;
169                     case "ver":
170                         WriteCommand(VersionName());
171                         break;
172                     default:
173                         WriteCommand("未知的命令!", Color.DarkGreen);
174                         break;
175                 }
176 
177             }
178             catch (IndexOutOfRangeException ex)
179             {
180                 WriteCommand("参数错误!Eg:
" + CommandList[arr[0]], Color.Tomato);
181             }
182             catch (Exception ex1)
183             {
184                 WriteCommand("错误:" + ex1.Message, Color.Tomato);
185             }
186         }
187 
188         //获取帮助文档
189         public string HelpDoc()
190         {
191             StringBuilder sbr = new StringBuilder();
192             sbr.AppendLine("帮助功能");
193             sbr.AppendLine("------------------------------------");
194             sbr.AppendLine("[命令]");
195             foreach (var i in CommandList)
196             {
197                 sbr.AppendLine(i.Value);
198             }
199             sbr.AppendLine();
200             sbr.AppendLine("[注意]");
201             sbr.AppendLine("命令与各参数使用空格隔开,如果需要使用空格,请使用“\s”");
202             sbr.AppendLine();
203             sbr.AppendLine();
204             sbr.AppendLine("------------------------------------");
205             sbr.AppendLine(VersionName());
206 
207             return sbr.ToString();
208         }
209 
210         public string VersionName()
211         {
212             StringBuilder sbr = new StringBuilder();
213             sbr.Append("字符串处理工具 - 脚本 v0.2  [墨云软件]");
214             return sbr.ToString();
215 
216         }
217 
218         /// <summary>
219         /// 工具栏按钮
220         /// </summary>
221         /// <param name="index"></param>
222         public override void BtnClick(int index)
223         {
224             MessageBox.Show(index.ToString());
225         }
226 
227     }
228 }
View Code

 可以看到第一行我使用了

//css_import StringExtension.cs  来引入了string扩展方法的脚本

接下来就是最后的脚本加载到软件中的部分了

 1         /// <summary>
 2         /// 初始化脚本
 3         /// </summary>
 4         /// <returns></returns>
 5         private bool IniteScrpit()
 6         {
 7 
 8     
 9             try
10             {
11 
12                 //脚本初始化方式  注意 脚本必须实现ICommand 接口
13                 AsmHelper asm = new AsmHelper(CSScript.Load(Config.ScriptPath,null,true));
14                 cmdEntity = (ICommand)asm.CreateObject("*");
15 
16                 cmdEntity.CurrMainForm = this;
17                 ((BaseCommand)cmdEntity).IniteBtn();
18                 cmdEntity.DefaultColor = txtCon.ForeColor;
19                 return true;
20             }
21             catch (Exception ex)
22             {
23                 MessageBox.Show( "脚本加载错误:
"+ex.Message,"提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
24                 Environment.Exit(0);
25                 return false;
26             }
27 
28 
29         }

 代码下载地址:

 http://pan.baidu.com/s/1eQyht9g

感谢的阅览,如有好的意见或建议欢迎不吝赐教。

最后宣传一下自己的抓包软件

NetAnalyzer下载地址

NetAnalzyer交流群:39753670 (PS 只提供交流平台,群主基本不说话^_^)

[转载请保留作者信息  作者:冯天文  网址:http://www.cnblogs.com/twzy/p/4925218.html]

原文地址:https://www.cnblogs.com/twzy/p/4925218.html