需求:string str = "Name=abc,Balance=123,GoodID=100891,OnlinePay=True,BankCardNumber=6225998999900982"字符串的规则:
1、数字都是正整数
2、如果 Balance == 0 时,没有 GoodID=100... 这一部分,而是:OT=1 这样的,即:
string str = "Name=abc,Balance=0,OT=1,OnlinePay=True,BankCardNumber=6225998999900982"
3、如果 OnlinePay=False 时,没有 BankCardNumber=... 这一部分,而是:Memo=abcdef.. 字符串,即:
string str = "Name=abc,Balance=0,OT=1,OnlinePay=False,Memo=abcdef"
4、以上 2 种例外可以同时存在:
string str = "Name=abc,Balance=10,GoodID=123,OnlinePay=True,BankCardNumber=6225998999900982"
string str = "Name=abc,Balance=10,GoodID=123,OnlinePay=False,Memo=A1VD"
string str = "Name=abc,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb"
5、有很多这样的字符串,用回车分隔,原串示例:Name=abc,Balance=100,GoodID=123,OnlinePay=True,BankCardNumber=6225998
Name=ced,Balance=10,GoodID=124,OnlinePay=False,Memo=A1VD
Name=frg,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb
Name=frgg,Balance=0,OT=4,OnlinePay=True,BankCardNumber=955998
....
要求用正则表达式提取每行的值到数据表中:DataTable:
---------------------------------------------------------------------------------------------
Name Balance GoodID OT OnlinePay BankCardNumber Memo
---------------------------------------------------------------------------------------------
abc 100 123 True 6225998
ced 10 124 False A1VD
frg 0 3 False A2VDvb
frgg 0 4 True 955998
.....
请高手指教,谢谢
1、数字都是正整数
2、如果 Balance == 0 时,没有 GoodID=100... 这一部分,而是:OT=1 这样的,即:
string str = "Name=abc,Balance=0,OT=1,OnlinePay=True,BankCardNumber=6225998999900982"
3、如果 OnlinePay=False 时,没有 BankCardNumber=... 这一部分,而是:Memo=abcdef.. 字符串,即:
string str = "Name=abc,Balance=0,OT=1,OnlinePay=False,Memo=abcdef"
4、以上 2 种例外可以同时存在:
string str = "Name=abc,Balance=10,GoodID=123,OnlinePay=True,BankCardNumber=6225998999900982"
string str = "Name=abc,Balance=10,GoodID=123,OnlinePay=False,Memo=A1VD"
string str = "Name=abc,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb"
5、有很多这样的字符串,用回车分隔,原串示例:Name=abc,Balance=100,GoodID=123,OnlinePay=True,BankCardNumber=6225998
Name=ced,Balance=10,GoodID=124,OnlinePay=False,Memo=A1VD
Name=frg,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb
Name=frgg,Balance=0,OT=4,OnlinePay=True,BankCardNumber=955998
....
要求用正则表达式提取每行的值到数据表中:DataTable:
---------------------------------------------------------------------------------------------
Name Balance GoodID OT OnlinePay BankCardNumber Memo
---------------------------------------------------------------------------------------------
abc 100 123 True 6225998
ced 10 124 False A1VD
frg 0 3 False A2VDvb
frgg 0 4 True 955998
.....
请高手指教,谢谢
解决方案 »
- 未将对象引用设置到对象的实例。
- jquery append(content)出现的问题!
- 如何去除Freextbox某些功能按钮?
- 简单问题俺不知道:开发WebSite,VS2005设定问题,生成的sln(suo)文件为什么在myDocument/Visual Studio 2005/Projects里?
- !!!! 菜鸟问题,刚刚学ASP.net 很简单的,帮帮忙啊
- ASP.net2.0中ObjectSources做多层程序的问题!!!!!
- 我写了一个函数用于截取字符串的,为什么不起作用,帮忙查一下。。。
- repeater里如何同时实现分页和排序?
- 报表的解决方案!!!
- WebService重复安装时界面上的"修复**服务"这一项如何舍弃掉~!
- ASP.NET中的div怎么能有id和runat属性
- 找一本asp.net的好书
{
string Name = m.Groups["Name"].Value 之类的
string Balance = m.Groups["Balance"].Value
string GoodID = m.Groups["GoodID"].Value; 如果 Balance = 0, GoodID = "";
.... 增加新行到 DataTable
}
按照楼主的需求,十分的有规律,直接Split是最快的
等下丢代码出来
我有一张Table tbA
栏位如下:Name,Balance,GoodID,OT,OnlinePay,BankCardNumber,Memo
其中Name是主键,Balance,OnlinePay两个栏位不为NULL,其他都可以为NULL
把目前有的字串资料转换成ROW,插入到这个表中
因此,只要把每行SPLIT出来就OK,然后用BatchUpdate 到Table中
但不想用 split,趁机会研究一下正则表达式
我写的这个,可以匹配出来一部分,分析如下:
虽然中间 GoodID, OT 二部分用的是 | 或的关系,但当适配了一条后,后面的字符串都只适配相同规则的了,即:第一行如果 Balance = 0, 则适配出了有 OT 的所有行
郁闷中...
foreach (Match m in mc)
{
DataRow dr = dtParts.NewRow();
dr["Name"] = m.Groups["Name"].ToString();
dr["Balance"] = m.Groups["Balance"].ToString();
dr["GoodID"] = m.Groups["GoodID"].ToString();
dr["OT"] = m.Groups["OT"].ToString();
dr["OnlinePay"] = m.Groups["OnlinePay"].ToString();
dr["BankCardNumber"] = m.Groups["BankCardNumber"].ToString();
dr["Memo"] = m.Groups["Memo"].ToString();
dt.Rows.Add(dr);
} return dt;在源串的最后加一个回车,这样都适配出来了。我这种写法是不是很笨啊,有高手搞个漂亮简单的结果指点一下,谢谢!
Name=ced,Balance=10,GoodID=124,OnlinePay=False,Memo=A1VD
Name=frg,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb
Name=frgg,Balance=0,OT=4,OnlinePay=True,BankCardNumber=955998
";
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Balance");
dt.Columns.Add("GoodID");
dt.Columns.Add("OT");
dt.Columns.Add("OnlinePay");
dt.Columns.Add("BankCardNumber");
dt.Columns.Add("Memo");
DataRow dr = dt.NewRow(); Regex reg = new Regex(@"(?im)^Name=(?<na>[a-z]+),Balance=(?<ba>\d+),(?:OT=(?<ot>\d+),)?(GoodID=(?<go>\d+),)?OnlinePay=(?<on>True|False),(BankCardNumber=(?<bc>\d+))?(?:Memo=(?<me>[a-z0-9]+))?\s*$");
MatchCollection mc = reg.Matches(test);
foreach (Match m in mc)
{
dr = dt.NewRow();
dr["Name"] = m.Groups["na"].Value ;
dr["Balance"] = m.Groups["ba"].Value ;
dr["GoodID"] = m.Groups["go"].Value ;
dr["OT"] = m.Groups["ot"].Value;
dr["OnlinePay"] = m.Groups["on"].Value;
dr["BankCardNumber"] = m.Groups["bc"].Value;
dr["Memo"] = m.Groups["me"].Value;
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
测试文本自行去创建,150W的文本有100Mb..
经测试
1.Split方式:使用流一行一行的读取,然后Splite的方式,150W行耗时 14秒
2.正则匹配的方式:直接内存溢出报错
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} int linecount = 0;
private void button1_Click(object sender, EventArgs e)
{
DataTable dtSplit = GetDataTable();
DataTable dtRegExp = GetDataTable();
DateTime begintime;
DateTime endtime ;
double spendseconds = 0; begintime = DateTime.Now;
SetValueBySplit(dtSplit);
endtime = DateTime.Now;
spendseconds = endtime.Subtract(begintime).TotalSeconds;
textBox1.Text += "共计" + linecount.ToString() + "行,使用Split耗费:" + spendseconds.ToString() + "秒 ";
dataGridView1.DataSource = dtSplit;
begintime = DateTime.Now;
SetValueByRegExp(dtRegExp);
endtime = DateTime.Now;
spendseconds = endtime.Subtract(begintime).TotalSeconds;
textBox1.Text += "使用RegExp耗费:" + spendseconds.ToString() + "秒 ";
//dataGridView2.DataSource = dtRegExp;
} private void SetValueBySplit(DataTable dt)
{
DataRow row = null;
String[] strLines = null;
String strFilePath = @"d:\test.txt";
if (File.Exists(strFilePath))
{
strLines = File.ReadAllLines(strFilePath);
linecount = strLines.Length;
foreach (string strLine in strLines)
{
row = dt.NewRow();
String[] strCols = strLine.Split(',');
foreach (String strCol in strCols)
{
int i = strCol.IndexOf('=') + 1;
String name = strCol.Substring(0, i - 1);
String value = strCol.Substring(i, strCol.Length - i);
row[name] = value;
}
dt.Rows.Add(row);
}
}
} private void SetValueByRegExp(DataTable dt)
{
DataRow row = null;
Regex reg = new Regex(@"(?im)^Name=(?<na>[a-z]+),Balance=(?<ba>\d+),(?:OT=(?<ot>\d+),)?(GoodID=(?<go>\d+),)?OnlinePay=(?<on>True|False),(BankCardNumber=(?<bc>\d+))?(?:Memo=(?<me>[a-z0-9]+))?\s*$");
MatchCollection mc = null;
String strFilePath = @"d:\test.txt";
String strContent = string.Empty;
if (File.Exists(strFilePath))
{
strContent = File.ReadAllText(strFilePath);
mc = reg.Matches(strContent);
foreach (Match m in mc)
{
row = dt.NewRow();
row["Name"] = m.Groups["na"].Value;
row["Balance"] = m.Groups["ba"].Value;
row["GoodID"] = m.Groups["go"].Value;
row["OT"] = m.Groups["ot"].Value;
row["OnlinePay"] = m.Groups["on"].Value;
row["BankCardNumber"] = m.Groups["bc"].Value;
row["Memo"] = m.Groups["me"].Value;
dt.Rows.Add(row);
}
}
} private static DataTable GetDataTable()
{
DataTable dt = new DataTable();
DataColumnCollection cols = dt.Columns;
cols.Add("Name", typeof(System.String));
cols.Add("Balance", typeof(System.String));
cols.Add("GoodID", typeof(System.String));
cols.Add("OT", typeof(System.String));
cols.Add("OnlinePay", typeof(System.String));
cols.Add("BankCardNumber", typeof(System.String));
cols.Add("Memo", typeof(System.String));
return dt;
}
}
}
其实怎么说呢,正则有它适用的场景,在做大数据量处理,且对效率要求非常高时,大多数场合确实不适合用正则,但是在小数据量处理,或是对效率没有要求的场合,正则是一个很不错的选择,当然,只是一种选择,并不一定适用于所有人,因为每个人掌握的知识点是不一样的,这就会影响开发效率当然,我写的正则如果说会导致内存溢出,那是使用方法不当,我写的正则也可以按行来处理的,只是在处理150w数据时,效率确实不高string test = @"Name=abc,Balance=100,GoodID=123,OnlinePay=True,BankCardNumber=6225998
Name=ced,Balance=10,GoodID=124,OnlinePay=False,Memo=A1VD
Name=frg,Balance=0,OT=3,OnlinePay=False,Memo=A2VDvb
Name=frgg,Balance=0,OT=4,OnlinePay=True,BankCardNumber=955998";
using (StreamWriter sw = new StreamWriter(@"g:\test.txt", true, Encoding.Default))
{
for (int i = 0; i <= 375000; i++)
{
sw.WriteLine(test);
}
}
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Balance");
dt.Columns.Add("GoodID");
dt.Columns.Add("OT");
dt.Columns.Add("OnlinePay");
dt.Columns.Add("BankCardNumber");
dt.Columns.Add("Memo");
DataRow dr = dt.NewRow();
Stopwatch sWatch = new Stopwatch();
sWatch.Start();
using (StreamReader sr = new StreamReader(@"g:\test.txt", Encoding.Default))
{
Regex reg = new Regex(@"(?im)^Name=(?<na>[a-z]+),Balance=(?<ba>\d+),(?:OT=(?<ot>\d+),)?(GoodID=(?<go>\d+),)?OnlinePay=(?<on>True|False),(BankCardNumber=(?<bc>\d+))?(?:Memo=(?<me>[a-z0-9]+))?\s*$", RegexOptions.Compiled);
string line = string.Empty;
while (sr.Peek() > -1)
{
line = sr.ReadLine();
Match m = reg.Match(line);
if(m.Success)
{
dr = dt.NewRow();
dr["Name"] = m.Groups["na"].Value;
dr["Balance"] = m.Groups["ba"].Value;
dr["GoodID"] = m.Groups["go"].Value;
dr["OT"] = m.Groups["ot"].Value;
dr["OnlinePay"] = m.Groups["on"].Value;
dr["BankCardNumber"] = m.Groups["bc"].Value;
dr["Memo"] = m.Groups["me"].Value;
dt.Rows.Add(dr);
}
}
}
sWatch.Stop();
textBox1.Text = "用时: " + sWatch.ElapsedMilliseconds + " ms";
dataGridView1.DataSource = dt;
//输出
用时: 28607 ms
正则并不是为某一需求而设计的,因此它要提供高度的抽象,这样就导致正则在处理某些问题时效率上有损失,当然,上面的正则还是可以优化的,但是并没有多大意义正则只用在合适的地方,而是否合适,要综合需求、开发效率、执行效率、可扩展性等等综合来考虑了