如何解析c#中的文本文件?
答案 0 :(得分:8)
检查这个有趣的方法,Linq To Text Files,非常好,你只需要一个IEnumerable<string>
方法,每个file.ReadLine()
产生一次,你就可以进行查询。
Here是另一篇更好地解释相同技术的文章。
答案 1 :(得分:5)
using (TextReader rdr = new StreamReader(fullFilePath))
{
string line;
while ((line = rdr.ReadLine()) != null)
{
// use line here
}
}
将变量“fullFilePath”设置为完整路径,例如。 C:\ TEMP \ myTextFile.txt
答案 2 :(得分:3)
算法可能如下所示:
解析一条线有几种方法。
从初学者角度来看,最简单的方法是使用String方法。
如果您需要更多挑战,那么您可以使用System.Text.RegularExpression库来解析您的文本。
答案 3 :(得分:1)
您可能希望使用辅助类,例如http://www.blackbeltcoder.com/Articles/strings/a-text-parsing-helper-class中描述的辅助类。
答案 4 :(得分:1)
通过多年分析CSV文件,包括破损或有边缘情况的文件,这里的代码几乎可以通过我的所有单元测试:
/// <summary>
/// Read in a line of text, and use the Add() function to add these items to the current CSV structure
/// </summary>
/// <param name="s"></param>
public static bool TryParseCSVLine(string s, char delimiter, char text_qualifier, out string[] array)
{
bool success = true;
List<string> list = new List<string>();
StringBuilder work = new StringBuilder();
for (int i = 0; i < s.Length; i++) {
char c = s[i];
// If we are starting a new field, is this field text qualified?
if ((c == text_qualifier) && (work.Length == 0)) {
int p2;
while (true) {
p2 = s.IndexOf(text_qualifier, i + 1);
// for some reason, this text qualifier is broken
if (p2 < 0) {
work.Append(s.Substring(i + 1));
i = s.Length;
success = false;
break;
}
// Append this qualified string
work.Append(s.Substring(i + 1, p2 - i - 1));
i = p2;
// If this is a double quote, keep going!
if (((p2 + 1) < s.Length) && (s[p2 + 1] == text_qualifier)) {
work.Append(text_qualifier);
i++;
// otherwise, this is a single qualifier, we're done
} else {
break;
}
}
// Does this start a new field?
} else if (c == delimiter) {
list.Add(work.ToString());
work.Length = 0;
// Test for special case: when the user has written a casual comma, space, and text qualifier, skip the space
// Checks if the second parameter of the if statement will pass through successfully
// e.g. "bob", "mary", "bill"
if (i + 2 <= s.Length - 1) {
if (s[i + 1].Equals(' ') && s[i + 2].Equals(text_qualifier)) {
i++;
}
}
} else {
work.Append(c);
}
}
list.Add(work.ToString());
// If we have nothing in the list, and it's possible that this might be a tab delimited list, try that before giving up
if (list.Count == 1 && delimiter != DEFAULT_TAB_DELIMITER) {
string[] tab_delimited_array = ParseLine(s, DEFAULT_TAB_DELIMITER, DEFAULT_QUALIFIER);
if (tab_delimited_array.Length > list.Count) {
array = tab_delimited_array;
return success;
}
}
// Return the array we parsed
array = list.ToArray();
return success;
}
但是,此函数实际上并不解析每个有效的CSV文件!某些文件中嵌入了换行符,您需要启用流式读取器将多行扫描在一起以返回一个数组。这是一个工具:
/// <summary>
/// Parse a line whose values may include newline symbols or CR/LF
/// </summary>
/// <param name="sr"></param>
/// <returns></returns>
public static string[] ParseMultiLine(StreamReader sr, char delimiter, char text_qualifier)
{
StringBuilder sb = new StringBuilder();
string[] array = null;
while (!sr.EndOfStream) {
// Read in a line
sb.Append(sr.ReadLine());
// Does it parse?
string s = sb.ToString();
if (TryParseCSVLine(s, delimiter, text_qualifier, out array)) {
return array;
}
}
// Fails to parse - return the best array we were able to get
return array;
}
作为参考,我放置了open source CSV code on code.google.com。
答案 5 :(得分:0)
如果您使用的不仅仅是一种简单的语言,请使用解析器生成器。它驱动了 me 坚果,但我听说过ANTLR的好东西(注意:在开始之前先阅读手册并阅读它。如果你之前使用过它以外的解析器生成器没有正确接近它,至少我没有)
还存在其他工具。
答案 6 :(得分:0)
如果不知道你所处的文本文件是什么类型,很难回答。但是,FileHelpers库有一套广泛的工具来帮助定长文件格式,多记录,分隔等。
答案 7 :(得分:0)
你是什么意思解析?解析通常意味着将输入拆分为令牌,如果您尝试实现编程语言,则可以执行此操作。如果您只是想阅读文本文件的内容,请查看System.IO.FileInfo。
答案 8 :(得分:0)
Pero答案的一个小改进:
FileInfo txtFile = new FileInfo("c:\myfile.txt");
if(!txtFile.Exists) { // error handling }
using (TextReader rdr = txtFile.OpenText())
{
// use the text file as Pero suggested
}
FileInfo类使您有机会在实际开始阅读之前对文件“执行操作”。您还可以在函数之间传递它作为文件位置的更好抽象(而不是使用完整路径字符串)。 FileInfo规范化路径,因此它绝对正确(例如,在适当的情况下转入/进入\),并允许您提取有关文件的额外数据 - 父目录,扩展名,仅限名称,权限等。
答案 9 :(得分:0)
首先,请确保您具有以下命名空间:
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
接下来,我们构建一个函数,将任何CSV输入字符串解析为DataTable:
public DataTable ParseCSV(string inputString) {
DataTable dt=new DataTable();
// declare the Regular Expression that will match versus the input string
Regex re=new Regex("((?<field>[^\",\\r\\n]+)|\"(?<field>([^\"]|\"\")+)\")(,|(?<rowbreak>\\r\\n|\\n|$))");
ArrayList colArray=new ArrayList();
ArrayList rowArray=new ArrayList();
int colCount=0;
int maxColCount=0;
string rowbreak="";
string field="";
MatchCollection mc=re.Matches(inputString);
foreach(Match m in mc) {
// retrieve the field and replace two double-quotes with a single double-quote
field=m.Result("${field}").Replace("\"\"","\"");
rowbreak=m.Result("${rowbreak}");
if (field.Length > 0) {
colArray.Add(field);
colCount++;
}
if (rowbreak.Length > 0) {
// add the column array to the row Array List
rowArray.Add(colArray.ToArray());
// create a new Array List to hold the field values
colArray=new ArrayList();
if (colCount > maxColCount)
maxColCount=colCount;
colCount=0;
}
}
if (rowbreak.Length == 0) {
// this is executed when the last line doesn't
// end with a line break
rowArray.Add(colArray.ToArray());
if (colCount > maxColCount)
maxColCount=colCount;
}
// create the columns for the table
for(int i=0; i < maxColCount; i++)
dt.Columns.Add(String.Format("col{0:000}",i));
// convert the row Array List into an Array object for easier access
Array ra=rowArray.ToArray();
for(int i=0; i < ra.Length; i++) {
// create a new DataRow
DataRow dr=dt.NewRow();
// convert the column Array List into an Array object for easier access
Array ca=(Array)(ra.GetValue(i));
// add each field into the new DataRow
for(int j=0; j < ca.Length; j++)
dr[j]=ca.GetValue(j);
// add the new DataRow to the DataTable
dt.Rows.Add(dr);
}
// in case no data was parsed, create a single column
if (dt.Columns.Count == 0)
dt.Columns.Add("NoData");
return dt;
}
现在我们有一个用于将字符串转换为DataTable的解析器,我们现在需要的是一个从CSV文件中读取内容并将其传递给ParseCSV函数的函数:
public DataTable ParseCSVFile(string path) {
string inputString="";
// check that the file exists before opening it
if (File.Exists(path)) {
StreamReader sr = new StreamReader(path);
inputString = sr.ReadToEnd();
sr.Close();
}
return ParseCSV(inputString);
}
现在,您可以使用CSV文件中的数据轻松填充DataGrid:
protected System.Web.UI.WebControls.DataGrid DataGrid1;
private void Page_Load(object sender, System.EventArgs e) {
// call the parser
DataTable dt=ParseCSVFile(Server.MapPath("./demo.csv"));
// bind the resulting DataTable to a DataGrid Web Control
DataGrid1.DataSource=dt;
DataGrid1.DataBind();
}
恭喜!您现在可以将CSV解析为DataTable。祝你的节目顺利。