平常喜欢写点小东西玩玩,既可以娱乐自己满足自己的虚荣心,又可以方便工作和学习,今天且拿出一个来,与大家一起分享!
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!
先看看我是怎么做的:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1kjM5QzNwcTMtIDO0IDN2MTMxEzMwETNxAjMtQzM0MDO08CXwETNxAjMvwFNzQzM4QzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
首先请无视工具栏那几个按钮,没啥作用(后面会提到),左侧两个文本框,上面的是输入,下面的是输出,右侧,是程序的核心部分,一个命令输入文本框(类似于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 }
当定义完毕之后就可以开始写脚本代码了
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]\r\n -- 字符串替换,[1] 目标,[2] 替换内容");
26 CommandList.Add("repregx", "repregx [1] [2]\r\n -- 字符串替换,[1] 正则表达式 ,[2] 替换内容");
27 CommandList.Add("idx", "idx [1]\r\n -- 顺序查找字符位置,[1] 字符");
28 CommandList.Add("ldx", "ldx [1]\r\n -- 逆序查找字符位置,[1] 字符");
29 CommandList.Add("len", "len\r\n -- 字符串长度");
30 CommandList.Add("spl", "spl [1]\r\n -- 字符串按指定字符分为行,[1]字符 ");
31 CommandList.Add("spe", "spe [1] [2] [3] [4]\r\n -- 字符串替换扩展,[1] 目标,[2] 左侧 [3] 右侧 [4] 替换内容");
32 CommandList.Add("sbr", "sbr\r\n -- 字符串封装StringBuilder");
33 CommandList.Add("regex", "regex [1]\r\n -- 正则表达式匹配");
34 CommandList.Add("popo", "popo\r\n -- 这都是泡沫");
35
36 CommandList.Add("print", "print [1]\r\n -- 向输出打印数据");
37 CommandList.Add("cls", "cls\r\n -- 清理命令区域内容");
38 CommandList.Add("?", "?\r\n -- 帮助 同 “help”");
39 CommandList.Add("help", "help\r\n -- 帮助 同 “?”");
40 CommandList.Add("cmdlst", "cmdlst\r\n -- 列出当前可用的命令");
41 CommandList.Add("ver", "ver\r\n -- 获取脚本版本");
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", "\t")
63 .Replace("\\d", "").Replace("\\n", "\n")
64 .Replace("\\r", "\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("O");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}\r\n", i.Value);
125 foreach (Group j in i.Groups)
126 {
127 regxsbr.AppendFormat(" {0}\r\n", 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:\r\n" + 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 }
可以看到第一行我使用了
//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( "脚本加载错误:\r\n"+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]
[转载请保留作者信息 作者:冯天文 ]