2013-05-16 32 views
5

Tôi đang sử dụng lớp TextFieldParser Lớp để đọc giá trị được phân tách bằng dấu phẩy (.csv). Các trường trong tệp này được đính kèm với dấu ngoặc kép như "Field1","Field2".TextFieldParser Class

Vì vậy, để đọc tệp, tôi đã đặt thuộc tính HasFieldsEnclosedInQuotes của đối tượng TextFieldParser thành true. Nhưng tôi nhận được một lỗi của MalformedLineException khi bất kỳ lĩnh vực chứa dấu nháy kép (`" +) ở phần đầu

Ví dụ:. ""Field2"with additional" Ở đây tôi sẽ thấy "Field2" with additional như sản lượng

Tuy nhiên, nếu " là bất cứ nơi nào trừ đầu tiên. vị trí sau đó nó hoạt động tốt. giống như phù hợp với "Field2 "with" additional" công trình hoàn toàn tốt đẹp và mang lại cho tôi Field2 "with" additional như đầu ra.

có ai có cùng một vấn đề? có cách nào tôi có thể giải quyết vấn đề này?

012.

Đây là mã của tôi:

Private Sub ReadTextFile(ByVal txtFilePath As String) 
    Dim myReader As tfp = New Microsoft.VisualBasic.FileIO.TextFieldParser(txtFilePath) 
    myReader.Delimiters = New String() {","} 
    myReader.TextFieldType = FileIO.FieldType.Delimited 
    myReader.HasFieldsEnclosedInQuotes = True 
    myReader.TrimWhiteSpace = True 
    Dim currentRow As String() 
    Dim headerRow As Integer = 0 

    While Not myReader.EndOfData 
     Try 
      currentRow = myReader.ReadFields() 

      'Read Header 
      If (headerRow = 0) Then 
       'Do work for Header Row 
       headerRow += 1 
      Else 
       'Do work for Data Row 
      End If 

     Catch ex As Exception 
      Dim errorline As String = myReader.ErrorLine 
     End Try 
    End While 

End Sub 

Đây là dữ liệu của tôi trong tập tin csv:

 
"Column1","Column2","Column3" 
"Value1","Value2",""A" Block in Building 123" 
+0

Thêm mã của bạn, vui lòng – nmat

+0

Trông giống như một lỗi hoặc thứ gì đó. Có lẽ bạn có thể xem xét không có dấu ngoặc kép trong các lĩnh vực của bạn nếu họ sẽ được kèm theo đó, nếu đó là một khả năng cho bạn – SysDragon

+0

Không, tôi không có quyền kiểm soát về điều đó. – optimusprime

Trả lời

-1

[Original câu trả lời]

Hãy thử điều này:

using System; 
using System.IO; 
using System.Linq; 

class Test 
{ 
    static void Main() 
    { 
     var file = "Test.txt"; 

     var r = File.ReadAllLines(file) 
      .Select((i, index) => new { Line = index, Fields = i.Split(new char[] { ',' }) }); 

     // header 
     var header = r.First(); 

     // do work for header 
     for (int j = 0; j < header.Fields.Count(); j++) 
     { 
      Console.Write("{0} ", header.Fields[j].Substring(1, header.Fields[j].Length-2)); 
     } 
     Console.WriteLine(); 

     var rows = r.Skip(1).ToList(); 

     // do work for rows 
     for (int i = 0; i < rows.Count; i++) 
     { 
      for (int j = 0; j < rows[i].Fields.Count(); j++) 
      { 
       Console.Write("{0} ", rows[i].Fields[j].Trim(new[] { '"' })); 
      } 
      Console.WriteLine(); 
     } 
    } 

} 

Note : Tôi đang đăng bài trong C# vì câu hỏi vẫn là b eing được gắn thẻ với nó.

Khi thẻ C# đã biến mất, vui lòng tham khảo http://converter.telerik.com/ để được trợ giúp chuyển đổi mã thành VB.

[câu trả lời Cập nhật]

Đang cố gắng một cách tiếp cận khác nhau (thời gian này, trong VB.Net):

Imports System 
Imports System.IO 
Imports System.Linq 

Class Test 
    Public Shared Sub Main() 
     Dim file__1 = "Test.txt" 

     Dim r = File.ReadAllLines(file__1).[Select](Function(i, index) New With { _ 
      .Line = index, _ 
      .Fields = i.Substring(1, i.Length - 2).Split(New String() {""","""}, StringSplitOptions.None) _ 
     }) 

     ' header 
     Dim header = r.First() 

     ' do work for header 
     For j As Integer = 0 To header.Fields.Count() - 1 
      Console.Write("{0} ", header.Fields(j)) 
     Next 
     Console.WriteLine() 

     Dim rows = r.Skip(1).ToList() 

     ' do work for rows 
     For i As Integer = 0 To rows.Count - 1 
      For j As Integer = 0 To rows(i).Fields.Count() - 1 
       Console.Write("{0} ", rows(i).Fields(j)) 
      Next 
      Console.WriteLine() 
     Next 
    End Sub 
End Class 
+1

Không, tôi không thể. Bởi vì trong csv có dấu phẩy (,) và dấu ngoặc kép (") cũng là một phần của dữ liệu. Chức năng tách không hoạt động trong trường hợp đó. Cảm ơn bạn đã đăng một mã cho tôi. Nó sẽ hoàn toàn hợp lý nếu dữ liệu của tôi không chứa dấu phẩy và dấu ngoặc kép. – optimusprime

+0

@optimusprime, còn bây giờ thì sao? –

9

dụ bạn ""A" Block" là CSV bị thay đổi; do đó, TextFieldParser có mọi quyền từ chối nó. Các CSV standard nói:

7. If double-quotes are used to enclose fields, then a double-quote 
    appearing inside a field must be escaped by preceding it with 
    another double quote. For example: 

    "aaa","b""bb","ccc" 

Nếu bạn mã hóa dữ liệu của bạn một cách chính xác, ví dụ: ...

"Column1","Column2","Column3" 
"Value1","Value2","""A"" Block in Building 123" 

... TextFieldParser hoạt động tốt và chính xác trả "A" Block in Building 123.

Vì vậy, bước đầu tiên là nói cho anh chàng sản xuất tệp CSV để tạo tệp CSV hợp lệ thay vì một cái gì đó trông giống như CSV-nhưng-không phải.

Nếu bạn không thể làm điều đó, bạn có thể muốn làm cho hai đi qua các tập tin:

  • Fix file bằng cách chuyển đổi nó thành một tập tin CSV "hợp lệ" (ví dụ bằng cách thay thế dấu ngoặc kép không theo dõi hoặc trước bằng dấu phẩy bằng hai dấu ngoặc kép).
  • Sau đó, TextFieldParser có thể phân tích cú pháp tệp CSV "hợp lệ" mà không gặp sự cố.