我要解析一个字符串,例如:string str = "姓名张三性别男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
我有一个关键字的配置文件
example.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<configration EName="姓名">
<Metadata>name</Metadata>
<Metadata>姓名</Metadata>
<Metadata>姓?名</Metadata>
</configration>
<configration EName="性别">
<Metadata>sex</Metadata>
<Metadata>性别</Metadata>
</configration>
<configration EName="出生日期">
<Metadata>出生日期</Metadata>
</configration>
<configration EName="居住地">
<Metadata>居住地</Metadata>
</configration>
<configration EName="工作年限">
<Metadata>工作年限</Metadata>
</configration>
<configration EName="户口">
<Metadata>户口</Metadata>
</configration>
<configration EName="目前年薪">
<Metadata>目前年薪</Metadata>
</configration>
<configration EName="地址">
<Metadata>地址</Metadata>
</configration>
</root>
-------------------------------------------------
我要得到的结果为:
张三
男
1980年11月19日
上海市
一年以上
上海
2万以下人民币
虹口区大连西路500号
--------------------------------------------------
这个字符串是不可知的,关键字也是允许用户配置的,而且这些关键字在字符串里可能存在,也可能不存在,可能存在的形式为:"姓名",也可能为:"name",不管是"姓名"还是"name",他们同属于一个父节点,因此解析出来的结果是要归结在一起的(可能会同时出现,也可能只出现其中一种).就是说如果是解析中文的时候,遇见"姓名"知道后面跟的是名字,英文的话遇见"name"知道后面是名字.还要一种情况就是关键字的位置是不固定的,可能关键字"居住地"在"性别"前面,等等,而且关键字要支持通配,比如说"姓_名",就是要匹配开头是姓最后是名中间只允许出现一个的字符串也是关键字,来解析结果.********************************************************
解决这个问题的朋友,单独开贴送500分.
我有一个关键字的配置文件
example.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<configration EName="姓名">
<Metadata>name</Metadata>
<Metadata>姓名</Metadata>
<Metadata>姓?名</Metadata>
</configration>
<configration EName="性别">
<Metadata>sex</Metadata>
<Metadata>性别</Metadata>
</configration>
<configration EName="出生日期">
<Metadata>出生日期</Metadata>
</configration>
<configration EName="居住地">
<Metadata>居住地</Metadata>
</configration>
<configration EName="工作年限">
<Metadata>工作年限</Metadata>
</configration>
<configration EName="户口">
<Metadata>户口</Metadata>
</configration>
<configration EName="目前年薪">
<Metadata>目前年薪</Metadata>
</configration>
<configration EName="地址">
<Metadata>地址</Metadata>
</configration>
</root>
-------------------------------------------------
我要得到的结果为:
张三
男
1980年11月19日
上海市
一年以上
上海
2万以下人民币
虹口区大连西路500号
--------------------------------------------------
这个字符串是不可知的,关键字也是允许用户配置的,而且这些关键字在字符串里可能存在,也可能不存在,可能存在的形式为:"姓名",也可能为:"name",不管是"姓名"还是"name",他们同属于一个父节点,因此解析出来的结果是要归结在一起的(可能会同时出现,也可能只出现其中一种).就是说如果是解析中文的时候,遇见"姓名"知道后面跟的是名字,英文的话遇见"name"知道后面是名字.还要一种情况就是关键字的位置是不固定的,可能关键字"居住地"在"性别"前面,等等,而且关键字要支持通配,比如说"姓_名",就是要匹配开头是姓最后是名中间只允许出现一个的字符串也是关键字,来解析结果.********************************************************
解决这个问题的朋友,单独开贴送500分.
姓名..性别..生日期..居住地..工作..户口..目前年薪..地址..
如果所有的串都象这种格式那就好办,如果不是....不好办
或者string[]传送
如楼上所说,如果碰到同关键字怎么办?"姓名:张姓名年龄:18";
我现在写了代码,如果没有重复的关键字没有问题,如果有的话就出现问题了
比如说:"个人说明""个人描述"其实可以归结为同样的内容,而不是两个内容.
中文简历"姓名",英文简历"name",就是一个内容,而不是两个内容.
如果遇到重复的关键字,我现在没有甚么好的解决方案.只能是采取优先原则,如果已经遇见了"姓名",那么后面遇见了"姓名"将不做为关键字处理.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;namespace WindowsApplication8
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
XmlDocument vXmlDocument = new XmlDocument();
vXmlDocument.Load("C:\\Temp\\example.xml");
XmlNodeList vXmlNodeList = vXmlDocument.GetElementsByTagName("configration");
string str = "姓名张三性别男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
string vName;
int i;
while (str.Length > 0)
{
vName = null;
foreach (XmlNode vXmlNode in vXmlNodeList)
{
foreach (XmlNode Metadata in vXmlNode.ChildNodes)
{
if (str.IndexOf(Metadata.InnerText) == 0)
{
vName = Metadata.InnerText;
goto loop;
}
}
} loop: ;
if (vName == null) break;
str = str.Remove(0, vName.Length);
i = str.Length;
foreach (XmlNode vXmlNode in vXmlNodeList)
{
foreach (XmlNode Metadata in vXmlNode.ChildNodes)
{
int j = str.IndexOf(Metadata.InnerText);
if (j >= 0)
i = i < j ? i : j;
}
}
if (i == str.Length)
{
textBox1.Text += str + "\r\n";
break;
}
else
{
textBox1.Text += str.Remove(i) + "\r\n";
str = str.Remove(0, i);
}
}
}
}
}
张三
男
1980年11月19日
上海市
一年以上
上海
2万以下人民币
虹口区大连西路500号
textBox1.Text += str.Remove(i)////重载方法少了参数
能在C#中看到Delphi的影子
回答问题也是种学习的方式
(主要是Delphi的人气渐渐少了,到这里混点分 :))to 楼主
我用的是2005调试
我再看看怎么把Remove换成Substring
{
XmlDocument vXmlDocument = new XmlDocument();
vXmlDocument.Load("C:\\Temp\\example.xml");
XmlNodeList vXmlNodeList = vXmlDocument.GetElementsByTagName("configration");
string str = "name张三sex男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
string vName;
int i;
while (str.Length > 0)
{
vName = null;
foreach (XmlNode vXmlNode in vXmlNodeList)
{
foreach (XmlNode Metadata in vXmlNode.ChildNodes)
{
if (str.IndexOf(Metadata.InnerText) == 0)
{
vName = Metadata.InnerText;
goto loop;
}
}
} loop: ;
if (vName == null) break;
str = str.Substring(vName.Length, str.Length - vName.Length);
i = str.Length;
foreach (XmlNode vXmlNode in vXmlNodeList)
{
foreach (XmlNode Metadata in vXmlNode.ChildNodes)
{
int j = str.IndexOf(Metadata.InnerText);
if (j >= 0)
i = i < j ? i : j;
}
}
if (i == str.Length)
{
textBox1.Text += str + "\r\n";
break;
}
else
{
textBox1.Text += str.Substring(0, i) + "\r\n";
str = str.Substring(i, str.Length - i);
}
}
你的代码考虑的情况少了,如果说
string str = "我们都是中国人姓名张三sex男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
这样的话就会出问题了,理想的情况下应该是找出字符串的第一个关键字,然后往下面解析
private XmlDocument vXmlDocument = new XmlDocument();
private string str = "我们都是中国人姓名张三sex男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
//private string str = "name张三sex男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";
private bool SearchName( // 搜索最近一个关键字
int AStartIndex, // 搜索开始序号
out int AReturnIndex, // 返回搜索到的位置
out string AReturnName)
{
AReturnIndex = str.Length;
AReturnName = null;
XmlNodeList vXmlNodeList = vXmlDocument.GetElementsByTagName("configration");
foreach (XmlNode vXmlNode in vXmlNodeList)
{
foreach (XmlNode Metadata in vXmlNode.ChildNodes)
{
int j = str.IndexOf(Metadata.InnerText, AStartIndex);
//关于正则表达式,可以修改这里实现
if ((j >= 0) && (AReturnIndex > j))
{
AReturnIndex = j;
AReturnName = Metadata.InnerText;
}
}
}
return AReturnName == null;
} private void button1_Click(object sender, EventArgs e)
{
vXmlDocument.Load("C:\\Temp\\example.xml");
int vLastIndex = 0;
int vSearchIndex;
string vSearchName; SearchName(0, out vSearchIndex, out vSearchName);
while (vSearchName != null)
{
//textBox1.Text += vSearchName + "="; // test
vLastIndex = vSearchIndex + vSearchName.Length;
SearchName(vLastIndex, out vSearchIndex, out vSearchName);
textBox1.Text += str.Substring(vLastIndex, vSearchIndex - vLastIndex) + "\r\n";
}
}
{
static void Main(string[] args)
{
//定义一个列表,用于存储所有关键字
List<string> list = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load(@"../../test.xml");
XmlNodeList nodes = doc.SelectNodes(@"//configration"); //定义一个数组用于存储
KeyWord[] keyWords = new KeyWord[nodes.Count];
int i = 0;
foreach (XmlNode node in nodes)
{
KeyWord key = new KeyWord();
string attri = node.Attributes["EName"].Value;
key.EName = attri;
if (!list.Contains(attri))
{
list.Add(attri);
}
foreach (XmlNode childnode in node.ChildNodes)
{
string text = childnode.InnerText;
key.MetaDatas.Add(text);
if (!list.Contains(text))
{
list.Add(text);
}
}
keyWords[i++] = key;
} //测试字符串
string str = "姓名张三sex男出生日期1980年11月19日居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号"; foreach (KeyWord key in keyWords)
{
//起始点
int startIndex = str.IndexOf(key.EName);
//终点
int endIndex = -1;
if (startIndex == -1)
{
//用子关键字进行搜索
foreach (string s in key.MetaDatas)
{
startIndex = str.IndexOf(s);
if (startIndex != -1)
{
startIndex += s.Length;
break;
}
}
}
else
{
startIndex += key.EName.Length;
} //看通过子关键字进行搜索后是否存在
if (startIndex != -1)
{
//查找终点,即找出离此关键字最近的关键字所在的位置
foreach (string s in list)
{
//先将此关键字及其子关键字从列表中排除
int index = str.Substring(startIndex).IndexOf(s);
if ((endIndex == -1 && index != -1) || (endIndex != -1 && index != -1 && index < endIndex))
{
//替换endIndex
endIndex = index;
}
}
if (endIndex == -1)
{
key.Value = str.Substring(startIndex);
}
else
{
key.Value = str.Substring(startIndex, endIndex);
}
}
} //测试
foreach (KeyWord key in keyWords)
{
Console.WriteLine(key.EName + ": " + key.Value);
}
}
}
//定义一个参数类
public class KeyWord
{
public string EName = "";
public List<string> MetaDatas = new List<string>();
public string Value = "";
}
姓名: 张三
性别: 男
出生日期: 1980年11月19日
居住地: 上海市
工作年限: 一年以上
户口: 上海
目前年薪: 2万以下人民币
地址: 虹口区大连西路500号string str = "sex男出生日期1980年11月19日姓名张三居住地上海市工作年限一年以上户口上海目前年薪2万以下人民币地址虹口区大连西路500号";输出如下:
姓名: 张三
性别: 男
出生日期: 1980年11月19日
居住地: 上海市
工作年限: 一年以上
户口: 上海
目前年薪: 2万以下人民币
地址: 虹口区大连西路500号.....
楼主给的是 <configration EName="姓名">
<Metadata>name</Metadata>
<Metadata>姓名</Metadata>
<Metadata>姓?名</Metadata>
</configration>EName应该就是字段名字,不知道EName要做什么。就是说EName可以是name,姓名,姓?名也作为字段名字?????????根据这个名字找对应的数据就可以了。============
我要得到的结果为:?
张三
男
1980年11月19日
上海市
一年以上
上海
2万以下人民币
虹口区大连西路500号不知道你的这些数据哪来的?什么格式?你的问题里并没有说明。既然是xml 格式,用xml的类就可以了
private int returnIndex(string indexValue)
{
string ss = indexValue.Substring(0,indexValue.IndexOf("."));
int _index = Convert.ToInt32(ss);
return _index;
} private int returnLength(string indexValue)
{
string ss = indexValue.Substring(indexValue.IndexOf("."),indexValue.Length-indexValue.IndexOf("."));
string cc = ss.Substring(1,ss.LastIndexOf(".")-1);
int _length = Convert.ToInt32(cc);
return _length; } private string returnValue(string indexValue)
{
int i = indexValue.LastIndexOf(".");
string ss = indexValue.Substring(i).Replace(".","");
return ss;
}
private void button2_Click(object sender, System.EventArgs e)
{
string str = "姓名: 中国人 居住地: 上海市性别: 男 出生日期: 1983年03月19日";
str = str.Replace(":","").Replace(" ","");
ArrayList al = new ArrayList();
sl = new SortedList();
al.Add("姓名");
al.Add("性别");
al.Add("出生日期");
al.Add("居住地");
for(int i=0;i<al.Count;i++)
{
Regex r = new Regex(al[i].ToString());
Match m = r.Match(str);
if(m.Success)
{
sl.Add(m.Index,m.Index+"."+m.Length+"."+m.Value);
} }
sList = sl.GetValueList();
for(int j=0;j<sl.Count;j++)
{
int index = returnIndex(sList[j].ToString());
int length = returnLength(sList[j].ToString());
if((j+1)<sl.Count)
{
this.richTextBox1.Text += returnValue(sList[j].ToString())+":"+str.Substring(index+length,returnIndex(trueValue(j+1))-(index+length))+"\n";
}
else
{
int v = returnIndex(trueValue(j+1))+returnLength(trueValue(j+1));
int f = str.Length;
this.richTextBox1.Text += returnValue(sList[j].ToString())+":"+str.Substring(v,str.Length-v)+"\n";
}
}
} private string trueValue(int k)
{
string newString = "";
if(k>=sl.Count)
{
for(int i=0;i<sl.Count;i++)
{
if(k == i+1)
{
newString = sList[i].ToString();
}
}
}
else
{
for(int m=0;m<sl.Count;m++)
{
if(k == m)
{
newString = sList[m].ToString();
}
}
}
return newString ;
}
//添几个关键字
ArrayList al=new ArrayList();
al.Add("姓名");al.Add("性别");al.Add("出生日期");al.Add("居住地");
al.Add("工作年限");al.Add("户口");al.Add("目前年薪");al.Add("地址");
ArrayList alIndex=new ArrayList();
Hashtable hs=new Hashtable();
for(int i=0;i<al.Count;i++)
{
string strKey=(string)al[i];
int iKeyIndex=str.IndexOf(strKey);
if(iKeyIndex>=0)
{
iKeyIndex+=strKey.Length;
if(!alIndex.Contains(iKeyIndex))
{
alIndex.Add(iKeyIndex);
hs.Add(iKeyIndex,strKey);
}
}
}
alIndex.Sort(null);
int[] iIndexs=(int[])alIndex.ToArray(typeof(int));
ArrayList alResult=new ArrayList();
for(int i=0;i<iIndexs.Length;i++)
{
if(i==iIndexs.Length-1)
alResult.Add(str.Substring(iIndexs[i]));
else
alResult.Add(str.Substring(iIndexs[i],iIndexs[i+1]-iIndexs[i]-hs[iIndexs[i+1]].ToString().Length));
}
//alResult
//有史以来,个人最变态写法之一