平常喜欢写点小东西玩玩,既可以娱乐自己满足自己的虚荣心,又可以方便工作和学习,今天且拿出一个来,与大家一起分享!
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 文件
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace StringTools
{
/// <summary>
/// 脚本所要集成的父类,提供一些基本方法
/// </summary>
public class BaseCommand
{ /// <summary>
/// 窗体主体,方便在以后开发中可以通过脚本方式直接调用窗体控件,如上面没实现任何功能的按钮
/// </summary>
public FrmMain CurrMainForm { get; set; }
/// <summary>
/// 用于记忆当前命令行控件的字体颜色
/// </summary>
public Color DefaultColor { get; set; }
/// <summary>
/// 命令行字典
/// </summary>
public Dictionary<string, string> CommandList { get; set; } /// <summary>
/// 向输出文本框写入文本
/// </summary>
/// <param name="message"></param>
public virtual void Print(string message)
{
CurrMainForm.txtOutput.Text = message;
CurrMainForm.txtCon.Write();
} /// <summary>
/// 清理命令行控件内容
/// </summary>
public void ClearCommand()
{
CurrMainForm.txtCon.Clear();
} /// <summary>
/// 向命令行控件写信息
/// </summary>
/// <param name="msg"></param>
public virtual void WriteCommand(string msg = "")
{
CurrMainForm.txtCon.Write(msg);
} /// <summary>
/// 向命令行控件写信息,并带有字体颜色
/// </summary>
/// <param name="msg"></param>
/// <param name="fontColor"></param>
public virtual void WriteCommand(string msg, Color fontColor)
{
CurrMainForm.txtCon.SelectionColor = fontColor;
CurrMainForm.txtCon.Write(msg);
CurrMainForm.txtCon.SelectionColor = DefaultColor;
} /// <summary>
/// 初始化5个按钮的单击事件
/// </summary>
internal void IniteBtn()
{
CurrMainForm.btnNo1.Click += OnbtnNo_Click;
CurrMainForm.btnNo2.Click += OnbtnNo_Click;
CurrMainForm.btnNo3.Click += OnbtnNo_Click;
CurrMainForm.btnNo4.Click += OnbtnNo_Click;
CurrMainForm.btnNo5.Click += OnbtnNo_Click;
}
/// <summary>
/// 单击事件方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnbtnNo_Click(object sender, EventArgs e)
{
BtnClick(int.Parse((sender as ToolStripButton).Tag.ToString()));
}
/// <summary>
/// 可重载方法,方便脚本中处理对应的事件方法
/// </summary>
/// <param name="index"></param>
public virtual void BtnClick(int index)
{ }
}
}
ICommand.cs 文件
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text; namespace StringTools
{
/// <summary>
/// 脚本所要是现实的接口
/// </summary>
public interface ICommand
{
/// <summary>
/// 命令执行方法
/// </summary>
/// <param name="cmd"></param>
/// <param name="inputText"></param>
void Exec(string cmd, string inputText);
/// <summary>
/// 帮助文档方法
/// </summary>
/// <returns></returns>
string HelpDoc();
/// <summary>
/// 命令列表,继承 BaseCommand 后默认实现
/// </summary>
Dictionary<string, string> CommandList { get; }
/// <summary>
/// 主界面 ,继承 BaseCommand 后默认实现(脚本设置无效)
/// </summary>
FrmMain CurrMainForm { get; set; }
/// <summary>
/// 命令行默认字体颜色,继承 BaseCommand 后默认实现(脚本设置无效)
/// </summary>
Color DefaultColor { get; set; }
}
}
当定义完毕之后就可以开始写脚本代码了
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文件的内容了
//css_import StringExtension.cs using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace StringTools
{
public class ExecScript : BaseCommand, ICommand
{
public ExecScript()
{
BuildList();
} Random rand=new Random (DateTime.Now.Millisecond); //生成命令列表,用于自动提示
private void BuildList()
{
CommandList = new Dictionary<string, string>();
CommandList.Add("rep", "rep [1] [2]\r\n -- 字符串替换,[1] 目标,[2] 替换内容");
CommandList.Add("repregx", "repregx [1] [2]\r\n -- 字符串替换,[1] 正则表达式 ,[2] 替换内容");
CommandList.Add("idx", "idx [1]\r\n -- 顺序查找字符位置,[1] 字符");
CommandList.Add("ldx", "ldx [1]\r\n -- 逆序查找字符位置,[1] 字符");
CommandList.Add("len", "len\r\n -- 字符串长度");
CommandList.Add("spl", "spl [1]\r\n -- 字符串按指定字符分为行,[1]字符 ");
CommandList.Add("spe", "spe [1] [2] [3] [4]\r\n -- 字符串替换扩展,[1] 目标,[2] 左侧 [3] 右侧 [4] 替换内容");
CommandList.Add("sbr", "sbr\r\n -- 字符串封装StringBuilder");
CommandList.Add("regex", "regex [1]\r\n -- 正则表达式匹配");
CommandList.Add("popo", "popo\r\n -- 这都是泡沫"); CommandList.Add("print", "print [1]\r\n -- 向输出打印数据");
CommandList.Add("cls", "cls\r\n -- 清理命令区域内容");
CommandList.Add("?", "?\r\n -- 帮助 同 “help”");
CommandList.Add("help", "help\r\n -- 帮助 同 “?”");
CommandList.Add("cmdlst", "cmdlst\r\n -- 列出当前可用的命令");
CommandList.Add("ver", "ver\r\n -- 获取脚本版本");
} //命令执行入口
public void Exec(string cmd, string inptuText)
{
if (string.IsNullOrEmpty(cmd))
{
WriteCommand();
return;
} string[] arr = cmd.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr[] != "regex")
{
for (int i = ; i < arr.Length; i++)
{
if (arr[] == "repregx" && i == )
continue;
arr[i] = arr[i].Replace("\\s", " ").Replace("\\t", "\t")
.Replace("\\d", "").Replace("\\n", "\n")
.Replace("\\r", "\r");
}
} try
{
switch (arr[])
{
case "rep":
Print(inptuText.Replace(arr[], arr[]));
break;
case "idx":
Print(inptuText.IndexOf(arr[]).ToString());
break;
case "ldx":
Print(inptuText.LastIndexOf(arr[]).ToString());
break;
case "len":
Print(inptuText.Length.ToString());
break;
case "spl":
Print(inptuText.SplitForRow(new char[] { arr[][] }));
break;
case "spe":
Print(inptuText.SplitWithOp(arr[].ToCharArray(), arr[], arr[], arr[]));
break;
case "sbr":
Print(inptuText.ToStringBuilder());
break;
case "popo":
StringBuilder popSbr=new StringBuilder();
for (int pop1 = ; pop1 < ; pop1++)
{
var popoRand=rand.Next(,);
switch (popoRand-)
{
case :popSbr.Append(".");break;
case :popSbr.Append("。");break;
case :popSbr.Append("o");break;
case :popSbr.Append("O");break;
case :popSbr.Append("");break;
case :popSbr.Append("゜");break;
case :popSbr.Append("○");break;
case :popSbr.Append("O");break;
case :popSbr.Append("〇");break;
}
if (pop1 % == )
{
popSbr.AppendLine();
} }
Print(popSbr.ToString());
break;
case "regex":
var ms = Regex.Matches(inptuText, arr[]);
StringBuilder regxsbr = new StringBuilder();
foreach (Match i in ms)
{
regxsbr.AppendLine("---------------------------");
regxsbr.AppendFormat("{0}\r\n", i.Value);
foreach (Group j in i.Groups)
{
regxsbr.AppendFormat(" {0}\r\n", j.Value);
}
} Print(regxsbr.ToString());
break;
case "repregx": Print(Regex.Replace(inptuText, arr[], arr[]));
break; case "cmdlst":
StringBuilder cmdListStr = new StringBuilder();
var cmdList=CommandList.Keys.ToArray();
for (int i = ; i <cmdList.Length; i++)
{
cmdListStr.Append(cmdList[i].PadRight(, ' '));
if (i% == )
{
cmdListStr.AppendLine();
}
}
WriteCommand(cmdListStr.ToString());
break;
case "print":
Print(arr[]);
break;
case "cls":
ClearCommand();
break;
case "?":
case "help":
if (arr.Length == && CommandList.Keys.Contains(arr[]))
{
WriteCommand(CommandList[arr[]]);
}
else
{
WriteCommand(HelpDoc());
}
break;
case "ver":
WriteCommand(VersionName());
break;
default:
WriteCommand("未知的命令!", Color.DarkGreen);
break;
} }
catch (IndexOutOfRangeException ex)
{
WriteCommand("参数错误!Eg:\r\n" + CommandList[arr[]], Color.Tomato);
}
catch (Exception ex1)
{
WriteCommand("错误:" + ex1.Message, Color.Tomato);
}
} //获取帮助文档
public string HelpDoc()
{
StringBuilder sbr = new StringBuilder();
sbr.AppendLine("帮助功能");
sbr.AppendLine("------------------------------------");
sbr.AppendLine("[命令]");
foreach (var i in CommandList)
{
sbr.AppendLine(i.Value);
}
sbr.AppendLine();
sbr.AppendLine("[注意]");
sbr.AppendLine("命令与各参数使用空格隔开,如果需要使用空格,请使用“\\s”");
sbr.AppendLine();
sbr.AppendLine();
sbr.AppendLine("------------------------------------");
sbr.AppendLine(VersionName()); return sbr.ToString();
} public string VersionName()
{
StringBuilder sbr = new StringBuilder();
sbr.Append("字符串处理工具 - 脚本 v0.2 [墨云软件]");
return sbr.ToString(); } /// <summary>
/// 工具栏按钮
/// </summary>
/// <param name="index"></param>
public override void BtnClick(int index)
{
MessageBox.Show(index.ToString());
} }
}
可以看到第一行我使用了
//css_import StringExtension.cs 来引入了string扩展方法的脚本
接下来就是最后的脚本加载到软件中的部分了
/// <summary>
/// 初始化脚本
/// </summary>
/// <returns></returns>
private bool IniteScrpit()
{ try
{ //脚本初始化方式 注意 脚本必须实现ICommand 接口
AsmHelper asm = new AsmHelper(CSScript.Load(Config.ScriptPath,null,true));
cmdEntity = (ICommand)asm.CreateObject("*"); cmdEntity.CurrMainForm = this;
((BaseCommand)cmdEntity).IniteBtn();
cmdEntity.DefaultColor = txtCon.ForeColor;
return true;
}
catch (Exception ex)
{
MessageBox.Show( "脚本加载错误:\r\n"+ex.Message,"提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
Environment.Exit();
return false;
} }
代码下载地址:
http://pan.baidu.com/s/1eQyht9g
感谢的阅览,如有好的意见或建议欢迎不吝赐教。
最后宣传一下自己的抓包软件
NetAnalzyer交流群:39753670 (PS 只提供交流平台,群主基本不说话^_^)
[转载请保留作者信息 作者:冯天文 网址:http://www.cnblogs.com/twzy/p/4925218.html]