转载

玩程序 之 一 . 字符串处理工具(可通过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!

先看看我是怎么做的:

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

首先请无视工具栏那几个按钮,没啥作用(后面会提到),左侧两个文本框,上面的是输入,下面的是输出,右侧,是程序的核心部分,一个命令输入文本框(类似于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的使用方式,

首先引用程序集

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

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

代码分别如下:

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

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

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

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 }  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( "脚本加载错误:/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 只提供交流平台,群主基本不说话^_^)

正文到此结束
Loading...