今天修改代码生成器解决了一个问题,偷懒将代码制作成Demo公开,换随笔,嘿嘿。
之所以使用递归算法实现。是希望每找到一个局部变量后,不再从头寻找。而是直接在新的起点处(nextTarget)搜索匹配。避免不必要的重复搜索。6》另外一个特别之处是,使用了一个特别常量:string constString = "123456789";具体作用,自己体会代码,
【原创源码】(03):利用简单递归算法,实现文本匹配、翻译。
欢迎大家发表意见(漏洞,性能等)。在博客园社区以外转载,请注明作者和出处。谢谢!
今天修改代码生成器解决了一个问题,偷懒将代码制作成Demo公开,换随笔,嘿嘿。
现在的需求是这样的:
1》用正则表达式解析出键值对:
输入:
<%@ TableOwner="dbo" %>
<%@ TableName="Demo" %>
输出:
一个Hashtable
方法:
public Hashtable GetWords(string text)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
//<%@ EntityName="Demo" %>
Hashtable hash = new Hashtable();
//MatchCollection mc = Regex.Matches(text, @"<\s*%[\s\S]*?%\s*>");
MatchCollection mc = Regex.Matches(text, @"<\s*%@[\s\S]*?%\s*>");
foreach (Match m in mc)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string temp = m.Value.Replace(" ", "");
//Regex.Replace(m.Value, "[\\s]{2,}", " ");
temp = temp.Replace("<%@", "");
temp = temp.Replace("\"%>", "");
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
string[] ss = temp.Split(new string[]
{ "=\"" }, StringSplitOptions.None);
![](/Images/OutliningIndicators/InBlock.gif)
hash.Add(ss[0], ss[1]);
}
return hash;
}2》插播一个在Hashtable中找键的方法:
public string GetStringFromHashtable(string search, Hashtable hash)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
object oo = hash[search];
if (oo == null)
return "";
else
return oo.ToString();
}3》将代码引用到的局部变量,匹配翻译成Hashtable中的值,换算输出:
输入:
CREATE PROCEDURE <%= OwnerString %>.<%= Prefix %><%= TableName %>_Insert2
输出:
CREATE PROCEDURE dbo.usp_Demo_Insert2
方法:
public string GetAttribute(string text, int target, Hashtable hash)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
string constString = "123456789";
text += constString;
//<%= _________ %>
string tag1 = "<%=";
string tag2 = "%>";
![](/Images/OutliningIndicators/InBlock.gif)
string key = String.Empty;
int keyBegin = 0, keyEnd = 0;
![](/Images/OutliningIndicators/InBlock.gif)
int nextTarget;
string nextText;
![](/Images/OutliningIndicators/InBlock.gif)
for (int i = target; i < text.Length - constString.Length; i++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (text.Substring(i, tag1.Length) == tag1)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
keyBegin = i + tag1.Length;
for (int j = keyBegin; j < text.Length - constString.Length; j++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (text.Substring(j, tag2.Length) == tag2)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
keyEnd = j - 1;
break;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
if (keyBegin < keyEnd)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
key = text.Substring(keyBegin, keyEnd - keyBegin + 1);
break;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
if (String.IsNullOrEmpty(key))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return text.Remove(text.Length - constString.Length);
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string value = GetStringFromHashtable(key.Trim(), hash);
nextTarget = keyBegin - tag1.Length + value.Length;
nextText = text.Substring(0, keyBegin - tag1.Length) + value + text.Substring(keyEnd + tag2.Length + 1);
![](/Images/OutliningIndicators/InBlock.gif)
nextText = nextText.Remove(nextText.Length - constString.Length);
return GetAttribute(nextText, nextTarget, hash);
}
}4》匹配算法的调用:
private void button1_Click(object sender, EventArgs e)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
this._Text = this.rtbDefault.Text;
//ArrayList arr = base.ReadWords(text);
this._KeysHash = this.GetWords(this._Text);
![](/Images/OutliningIndicators/InBlock.gif)
this.rtbCode.Text = this.GetAttribute(this._Text, 0, this._KeysHash);
this.tbcOptions.SelectedIndex = 1;
}5》总结:
之所以使用递归算法实现。是希望每找到一个局部变量后,不再从头寻找。而是直接在新的起点处(nextTarget)搜索匹配。避免不必要的重复搜索。
第一次搜索的时候,制定搜索开始为0(this.rtbCode.Text = this.GetAttribute(this._Text, 0, this._KeysHash);)
当全文不再有局部变量需要替换的时候:递归算法必须退出!!
if (String.IsNullOrEmpty(key))
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
return text.Remove(text.Length - constString.Length);
}6》另外一个特别之处是,使用了一个特别常量:
string constString = "123456789";具体作用,自己体会代码,在文本较大的时候,能提高一半效率。
7》源代码下载地址:
https://files.cnblogs.com/ClarkChan/TextMatch_061117.rar注意勿删此文件TextMatch2006\TextMatch\bin\Debug\Templates\Sql.txt,运行Demo必须。
Demo很简单,高手路过就好~~随笔也写的粗糙,不明白的,看代码吧。
注意!在博客园社区以外转载,必须注明:
作者:Clark Chan
和原文出处:
http://clarkchan.cnblogs.com/否则谢绝转载!