C# 拆分逗号分隔值(CSV)
如何在c sharp中拆分CSV文件?如何显示它?一次读取一行文件,然后C# 拆分逗号分隔值(CSV),c#,csv,C#,Csv,如何在c sharp中拆分CSV文件?如何显示它?一次读取一行文件,然后 foreach (String line in line.Split(new char[] { ',' })) Console.WriteLine(line); 显示在哪里?关于拆分,最好的方法是使用一个好的库 非常好,我可以衷心推荐 使用幼稚方法的问题在于,这些方法通常会失败,甚至在不考虑性能的情况下,存在大量的考虑因素: 如果文本包含逗号怎么办 支持多种现有格式(由分号分隔,或由引号包围的文本,或单引号等)
foreach (String line in line.Split(new char[] { ',' }))
Console.WriteLine(line);
显示在哪里?关于拆分,最好的方法是使用一个好的库 非常好,我可以衷心推荐 使用幼稚方法的问题在于,这些方法通常会失败,甚至在不考虑性能的情况下,存在大量的考虑因素:
- 如果文本包含逗号怎么办
- 支持多种现有格式(由分号分隔,或由引号包围的文本,或单引号等)
- 还有很多其他的
- 这是我偶尔使用的CSV解析器
用法:(dgvMyView是一种数据网格类型。)
类别:
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class CSVReader
{
private const string ESCAPE_SPLIT_REGEX = "({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*";
private string[] FieldNames;
private List<string[]> Records;
private int ReadIndex;
public CSVReader(string File)
{
Records = new List<string[]>();
string[] Record = null;
StreamReader Reader = new StreamReader(File);
int Index = 0;
bool BlankRecord = true;
FieldNames = GetEscapedSVs(Reader.ReadLine());
while (!Reader.EndOfStream)
{
Record = GetEscapedSVs(Reader.ReadLine());
BlankRecord = true;
for (Index = 0; Index <= Record.Length - 1; Index++)
{
if (!string.IsNullOrEmpty(Record[Index])) BlankRecord = false;
}
if (!BlankRecord) Records.Add(Record);
}
ReadIndex = -1;
Reader.Close();
}
private string[] GetEscapedSVs(string Data)
{
return GetEscapedSVs(Data, ",", "\"");
}
private string[] GetEscapedSVs(string Data, string Separator, string Escape)
{
string[] Result = null;
int Index = 0;
int PriorMatchIndex = 0;
MatchCollection Matches = Regex.Matches(Data, string.Format(ESCAPE_SPLIT_REGEX, Separator, Escape));
Result = new string[Matches.Count];
for (Index = 0; Index <= Result.Length - 2; Index++)
{
Result[Index] = Data.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
Result[Result.Length - 1] = Data.Substring(PriorMatchIndex);
for (Index = 0; Index <= Result.Length - 1; Index++)
{
if (Regex.IsMatch(Result[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) Result[Index] = Result[Index].Substring(1, Result[Index].Length - 2);
Result[Index] = Result[Index].Replace(Escape + Escape, Escape);
if (Result[Index] == null) Result[Index] = "";
}
return Result;
}
public int FieldCount
{
get { return FieldNames.Length; }
}
public string GetString(int Index)
{
return Records[ReadIndex][Index];
}
public string GetName(int Index)
{
return FieldNames[Index];
}
public bool Read()
{
ReadIndex = ReadIndex + 1;
return ReadIndex < Records.Count;
}
public void DisplayResults(DataGridView DataView)
{
DataGridViewColumn col = default(DataGridViewColumn);
DataGridViewRow row = default(DataGridViewRow);
DataGridViewCell cell = default(DataGridViewCell);
DataGridViewColumnHeaderCell header = default(DataGridViewColumnHeaderCell);
int Index = 0;
ReadIndex = -1;
DataView.Rows.Clear();
DataView.Columns.Clear();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
col = new DataGridViewColumn();
col.CellTemplate = new DataGridViewTextBoxCell();
header = new DataGridViewColumnHeaderCell();
header.Value = GetName(Index);
col.HeaderCell = header;
DataView.Columns.Add(col);
}
while (Read())
{
row = new DataGridViewRow();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
cell = new DataGridViewTextBoxCell();
cell.Value = GetString(Index).ToString();
row.Cells.Add(cell);
}
DataView.Rows.Add(row);
}
}
}
使用System.IO;
使用System.Text.RegularExpressions;
使用System.Windows.Forms;
公共类CSVReader
{
private const string ESCAPE_splitregex=“({1}[^{1}]*{1})*(?{0})({1}[^{1}]*{1})*”;
私有字符串[]字段名;
私人名单记录;
私有int-ReadIndex;
公共CSVReader(字符串文件)
{
记录=新列表();
字符串[]记录=null;
StreamReader=新的StreamReader(文件);
int指数=0;
bool BlankRecord=true;
FieldNames=GetEscapedSVs(Reader.ReadLine());
而(!Reader.EndOfStream)
{
Record=GetEscapedSVs(Reader.ReadLine());
BlankRecord=true;
对于(Index=0;Index我一直在使用Microsoft.VisualBasic.FileIO命名空间中的,用于我正在处理的C#项目。它将处理复杂的问题,例如嵌入逗号或括在引号中的字段等。它返回字符串[]而且,除了CSV文件外,还可以用于解析几乎任何类型的结构化文本文件。我已经得到了查询结果。这就像我使用io.file读取了一个文件一样简单。所有文本都存储到一个字符串中。之后,我用分隔符拆分。代码如下所示
using System;
using System.Collections.Generic;
using System.Text;
namespace CSV
{
class Program
{
static void Main(string[] args)
{
string csv = "user1, user2, user3,user4,user5";
string[] split = csv.Split(new char[] {',',' '});
foreach(string s in split)
{
if (s.Trim() != "")
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
以下函数从CSV文件中提取一行,并将其拆分为列表
参数:
字符串行=要拆分的行
string textQualifier=什么(如果有)文本限定符(即“或”\“或””)
char delim=字段分隔符(即“,”或“;”或“|”或“\t”)
int colCount=预期的字段数(0表示不检查)
用法示例:
List<string> fields = SplitLine(line, "\"", ',', 5);
// or
List<string> fields = SplitLine(line, "'", '|', 10);
// or
List<string> fields = SplitLine(line, "", '\t', 0);
List fields=SplitLine(行“\”,“,”,5);
//或
列表字段=拆分行(行“,”,“|”,10);
//或
列表字段=拆分行(行“,”\t',0);
功能:
private List<string> SplitLine(string line, string textQualifier, char delim, int colCount)
{
List<string> fields = new List<string>();
string origLine = line;
char textQual = '"';
bool hasTextQual = false;
if (!String.IsNullOrEmpty(textQualifier))
{
hasTextQual = true;
textQual = textQualifier[0];
}
if (hasTextQual)
{
while (!String.IsNullOrEmpty(line))
{
if (line[0] == textQual) // field is text qualified so look for next unqualified delimiter
{
int fieldLen = 1;
while (true)
{
if (line.Length == 2) // must be final field (zero length)
{
fieldLen = 2;
break;
}
else if (fieldLen + 1 >= line.Length) // must be final field
{
fieldLen += 1;
break;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == textQual) // escaped text qualifier
{
fieldLen += 2;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == delim) // must be end of field
{
fieldLen += 1;
break;
}
else // not a delimiter
{
fieldLen += 1;
}
}
string escapedQual = textQual.ToString() + textQual.ToString();
fields.Add(line.Substring(1, fieldLen - 2).Replace(escapedQual, textQual.ToString())); // replace escaped qualifiers
if (line.Length >= fieldLen + 1)
{
line = line.Substring(fieldLen + 1);
if (line == "") // blank final field
{
fields.Add("");
}
}
else
{
line = "";
}
}
else // field is not text qualified
{
int fieldLen = line.IndexOf(delim);
if (fieldLen != -1) // check next delimiter position
{
fields.Add(line.Substring(0, fieldLen));
line = line.Substring(fieldLen + 1);
if (line == "") // final field must be blank
{
fields.Add("");
}
}
else // must be last field
{
fields.Add(line);
line = "";
}
}
}
}
else // if there is no text qualifier, then use existing split function
{
fields.AddRange(line.Split(delim));
}
if (colCount > 0 && colCount != fields.Count) // count doesn't match expected so throw exception
{
throw new Exception("Field count was:" + fields.Count.ToString() + ", expected:" + colCount.ToString() + ". Line:" + origLine);
}
return fields;
}
private List SplitLine(字符串行、字符串textQualifier、char delim、int colCount)
{
列表字段=新列表();
字符串origLine=行;
char textQual=“”;
bool-hasTextQual=false;
如果(!String.IsNullOrEmpty(textQualifier))
{
hasTextQual=真;
textQual=textQualifier[0];
}
如果(hasTextQual)
{
而(!String.IsNullOrEmpty(line))
{
如果(行[0]==textQual)//字段是文本限定的,则查找下一个非限定分隔符
{
int fieldLen=1;
while(true)
{
if(line.Length==2)//必须是最终字段(零长度)
{
fieldLen=2;
打破
}
else if(fieldLen+1>=line.Length)//必须是最终字段
{
fieldLen+=1;
打破
}
else if(line[fieldLen]==textQual&&line[fieldLen+1]==textQual)//转义文本限定符
{
fieldLen+=2;
}
else if(line[fieldLen]==textQual&&line[fieldLen+1]==delim)//必须是字段的结尾
{
fieldLen+=1;
打破
}
else//不是分隔符
{
fieldLen+=1;
}
}
字符串escapedQual=textQual.ToString()+textQual.ToString();
Add(line.Substring(1,fieldLen-2).Replace(escapedQual,textQual.ToString());//Replace转义限定符
如果(line.Length>=fieldLen+1)
{
line=line.子字符串(fieldLen+1);
if(line==“”)//最终字段为空
{
字段。添加(“”);
}
}
其他的
{
第“”行;
}
}
else//字段不是文本限定的
{
int fieldLen=行索引(delim);
if(fieldLen!=-1)//检查下一个分隔符位置
{
fields.Add(line.Substring(0,fieldLen));
line=line.子字符串(fieldLen+1);
if(line==“”)//最后一个字段必须为空
{
字段。添加(“”);
}
}
else//必须是最后一个字段
{
字段。添加(行);
第“”行;
}
}
}
}
else//如果没有文本限定符,则使用现有的拆分函数
{
fields.AddRange(line.Split(delim));
}
如果(colCount>0&&colCount!=fields.Count)//Count与预期不匹配,则引发异常
{
抛出新异常(“字段计数为:“+fields.count.ToString()+”,应为:“+colCount.ToString()+”。行:“+origLine”);
}
返回字段;
}
ImportMicorosoft.VisualBasic
作为参考(我知道,它还不错),并使用Microsoft.VisualBasic.FileIO.TextFieldParser
-
private List<string> SplitLine(string line, string textQualifier, char delim, int colCount)
{
List<string> fields = new List<string>();
string origLine = line;
char textQual = '"';
bool hasTextQual = false;
if (!String.IsNullOrEmpty(textQualifier))
{
hasTextQual = true;
textQual = textQualifier[0];
}
if (hasTextQual)
{
while (!String.IsNullOrEmpty(line))
{
if (line[0] == textQual) // field is text qualified so look for next unqualified delimiter
{
int fieldLen = 1;
while (true)
{
if (line.Length == 2) // must be final field (zero length)
{
fieldLen = 2;
break;
}
else if (fieldLen + 1 >= line.Length) // must be final field
{
fieldLen += 1;
break;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == textQual) // escaped text qualifier
{
fieldLen += 2;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == delim) // must be end of field
{
fieldLen += 1;
break;
}
else // not a delimiter
{
fieldLen += 1;
}
}
string escapedQual = textQual.ToString() + textQual.ToString();
fields.Add(line.Substring(1, fieldLen - 2).Replace(escapedQual, textQual.ToString())); // replace escaped qualifiers
if (line.Length >= fieldLen + 1)
{
line = line.Substring(fieldLen + 1);
if (line == "") // blank final field
{
fields.Add("");
}
}
else
{
line = "";
}
}
else // field is not text qualified
{
int fieldLen = line.IndexOf(delim);
if (fieldLen != -1) // check next delimiter position
{
fields.Add(line.Substring(0, fieldLen));
line = line.Substring(fieldLen + 1);
if (line == "") // final field must be blank
{
fields.Add("");
}
}
else // must be last field
{
fields.Add(line);
line = "";
}
}
}
}
else // if there is no text qualifier, then use existing split function
{
fields.AddRange(line.Split(delim));
}
if (colCount > 0 && colCount != fields.Count) // count doesn't match expected so throw exception
{
throw new Exception("Field count was:" + fields.Count.ToString() + ", expected:" + colCount.ToString() + ". Line:" + origLine);
}
return fields;
}
string sLine;
sLine = "First,\"Second\",\"Even,With,Commas\",,Normal,\"Sentence,with \"\"different\"\" problems\",3,4,5";
// 1. Split line by separator; do not split if separator is within quotes
string Separator = ",";
string Escape = '"'.ToString();
MatchCollection Matches = Regex.Matches(sLine,
string.Format("({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*", Separator, Escape));
string[] asColumns = new string[Matches.Count + 1];
int PriorMatchIndex = 0;
for (int Index = 0; Index <= asColumns.Length - 2; Index++)
{
asColumns[Index] = sLine.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
asColumns[asColumns.Length - 1] = sLine.Substring(PriorMatchIndex);
// 2. Remove quotes
for (int Index = 0; Index <= asColumns.Length - 1; Index++)
{
if (Regex.IsMatch(asColumns[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) // If "Text" is sourrounded by quotes (but ignore double quotes => "Leave ""inside"" quotes")
{
asColumns[Index] = asColumns[Index].Substring(1, asColumns[Index].Length - 2); // "Text" => Text
}
asColumns[Index] = asColumns[Index].Replace(Escape + Escape, Escape); // Remove double quotes ('My ""special"" text' => 'My "special" text')
if (asColumns[Index] == null) asColumns[Index] = "";
}