我有一个小程序来读取CSV文件以构建数据表。如果逗号在引号之间,则一个要求是忽略逗号(名称中的逗号等)。例。
Name, Age, Location
"Henderson, David", 32, London
John Smith, 19, Belfast
程序应该忽略Henderson之后的逗号,并将Henderson,David视为一个字段。我当前的代码无法完成这项工作,最后添加额外的列。那么我该如何实现呢?解决方案不应该替换引号之间的逗号。感谢。
我目前的代码。
Public Function BuildDataTable() As DataTable
Dim myTable As DataTable = New DataTable("MyTable")
Dim i As Integer
Dim myRow As DataRow
Dim fieldValues As String()
Dim myReader As StreamReader = New StreamReader(_fileFullPath, Encoding.GetEncoding("iso-8859-1"))
Try
fieldValues = myReader.ReadLine().Split(_seperator)
'Create data columns accordingly
If _hasheader = False Then
For i = 0 To fieldValues.Length() - 1
myTable.Columns.Add(New DataColumn("Column(" & i & ")"))
Next
Else
'if the file has header, take the first row as header for datatable
For i = 0 To fieldValues.Length() - 1
myTable.Columns.Add(New DataColumn(fieldValues(i).Replace(" ", "")))
Next
End If
myRow = myTable.NewRow
If _hasheader = False Then
For i = 0 To fieldValues.Length() - 1
myRow.Item(i) = fieldValues(i).ToString
Next
myTable.Rows.Add(myRow)
End If
While myReader.Peek() <> -1
fieldValues = myReader.ReadLine().Split(_seperator)
myRow = myTable.NewRow
For i = 0 To fieldValues.Length() - 1
myRow.Item(i) = fieldValues(i).Trim.ToString
Next
If Not csv2xml.AreAllColumnsEmpty(myRow) = True Then
myTable.Rows.Add(myRow)
End If
End While
Catch ex As Exception
End Try
End Function
答案 0 :(得分:3)
您希望在CSV中使用双引号字符作为文本限定符。如果字段包含在文本限定符中,则文本限定符允许您在字段值中使用字段分隔符。
你可以自己编程,但这是一个错误。有很多免费且功能强大的CSV解析器可以为您完成此任务。由于您使用的是Visual Basic,因此可以查看TextFieldParser
class。
您仍然需要编写将CSV内容写入DataTable的代码。
我发现以下似乎有效:
http://www.vbcode.com/asp/showsn.asp?theID=13645
另一个选项是在GenericParser
处codeproject.com结束。不要让文章中的代码用C#编写的事实打扰你;您仍然可以在项目中引用DLL(GenericParsing.dll)并在VB中使用它。
这个解析器的好处是它包含了一个可以用来从CSV返回DataTable的方法。以下是一个适用于您的示例数据的示例:
Using parser As New GenericParsing.GenericParserAdapter(CSV_FILE_FULLNAME)
parser.ColumnDelimiter = ","
parser.TextQualifier = """"
parser.FirstRowHasHeader = True
Dim dt As DataTable = parser.GetDataTable()
End Using
答案 1 :(得分:0)
我不熟悉Visual Basic,但我认为你不应该使用Split()
函数来分割行。
fieldValues = myReader.ReadLine().Split(_seperator) ' DO NOT do this
相反,编写自己的split函数,逐个读取每个字符。然后有一个标志来记录你是否在双引号之间。
<强>更新强>
对不起,我对VB或C#知之甚少,无法编写可运行的代码片段。 请阅读此伪代码(事实上它是JavaScript)...希望它有用。
function split_with_quote(string, delimiter, quotation) {
if (delimiter == null) delimiter = ',';
if (quotation == null) quotation = '"';
var in_quotation = false;
var result = [];
var part = '';
for (var i = 0; i < string.length; i++) {
var ch = string[i];
if (ch == quotation) in_quotation = !in_quotation;
if (ch == delimiter && !in_quotation) {
result.push(part);
part = '';
} else {
if (ch != quotation) part += ch;
}
}
return result;
}
a = 'abc,def,"ghi,jkl",123';
split_with_quote(a); // ["abc", "def", "ghi,jkl"]