Tôi đang xem các tệp phân tách của tôi (ví dụ: CSV, tab tách biệt, v.v.) dựa trên ngăn xếp MS nói chung và .net cụ thể. Công nghệ duy nhất tôi loại trừ là SSIS, bởi vì tôi đã biết nó sẽ không đáp ứng được nhu cầu của tôi.Tùy chọn phân tích cú pháp CSV với .NET
Vì vậy, lựa chọn của tôi xuất hiện là:
- Regex.Split
- TextFieldParser
- OLEDB CSV Parser
Tôi có hai tiêu chí tôi phải đáp ứng. Thứ nhất, cho các tập tin sau đây, trong đó có hai hàng logic của dữ liệu (và năm hàng vật lý hoàn toàn):
101, Bob, "Keeps his house ""clean"".
Needs to work on laundry."
102, Amy, "Brilliant.
Driven.
Diligent."
Các kết quả phân tích phải nhường hai logic "hàng", gồm ba dây (hoặc cột) mỗi . Chuỗi hàng/cột thứ ba phải lưu giữ các dòng mới! Nói cách khác, trình phân tích cú pháp phải nhận ra khi các dòng "tiếp tục" trên hàng vật lý tiếp theo, do bộ định dạng văn bản "không được tiết lộ".
Tiêu chí thứ hai là dấu phân cách và dấu phân cách văn bản phải được định cấu hình, cho mỗi tệp. Dưới đây là hai chuỗi, lấy từ các tập tin khác nhau, mà tôi phải có khả năng phân tích:
var first = @"""This"",""Is,A,Record"",""That """"Cannot"""", they say,"","""",,""be"",rightly,""parsed"",at all";
var second = @"~This~|~Is|A|Record~|~ThatCannot~|~be~|~parsed~|at all";
Một phân tích thích hợp của chuỗi "đầu tiên" sẽ là:
- này
- là, A, Ghi
- That "không thể", họ nói,
- _
- _
- được
- đúng
- phân tích cú pháp
- ở tất cả
Các '_' chỉ đơn giản có nghĩa là một trống bị bắt - Tôi không muốn có một thanh dưới đen xuất hiện.
Một giả thiết quan trọng có thể được thực hiện về các tệp phẳng được phân tích cú pháp: sẽ có một số cột cố định cho mỗi tệp.
Bây giờ, hãy đi sâu vào các tùy chọn kỹ thuật.
REGEX
Thứ nhất, nhiều phản ứng nhận xét rằng regex "không phải là cách tốt nhất" để đạt được mục tiêu.Tôi đã, tuy nhiên, hãy tìm một commenter who offered an excellent CSV regex:
var regex = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
var Regex.Split(first, regex).Dump();
Kết quả, áp dụng cho chuỗi "đầu tiên" là khá tuyệt vời:
- "Đây"
- "Có, A, Record"
- "That "" không thể" "họ nói,"
- ""
- _
- "b e"
- đúng
- 'phân tích'
- ở tất cả
Nó sẽ được tốt đẹp nếu có dấu ngoặc kép được dọn dẹp, nhưng tôi có thể dễ dàng đối phó với điều đó như một bước sau quá trình. Nếu không, phương pháp này có thể được sử dụng để phân tích cả hai chuỗi mẫu "đầu tiên" và "thứ hai", miễn là regex được sửa đổi cho dấu ngã và ký hiệu ống cho phù hợp. Xuất sắc!
Nhưng vấn đề thực sự liên quan đến tiêu chí nhiều dòng. Trước khi có thể áp dụng regex cho một chuỗi, tôi phải đọc toàn bộ "hàng" hợp lý từ tệp. Thật không may, tôi không biết có bao nhiêu hàng vật lý cần đọc để hoàn thành hàng logic, trừ khi tôi có máy regex/state.
Vì vậy, điều này sẽ trở thành vấn đề "gà và trứng". Lựa chọn tốt nhất của tôi là đọc toàn bộ tệp vào bộ nhớ dưới dạng một chuỗi khổng lồ và để regex phân loại nhiều dòng (tôi không kiểm tra liệu regex ở trên có thể xử lý điều đó) hay không. Nếu tôi đã có một tập tin 10 gig, điều này có thể là một chút bấp bênh.
Bật tùy chọn tiếp theo.
TextFieldParser
Ba dòng mã sẽ làm cho các vấn đề với tùy chọn này rõ ràng:
var reader = new Microsoft.VisualBasic.FileIO.TextFieldParser(stream);
reader.Delimiters = new string[] { @"|" };
reader.HasFieldsEnclosedInQuotes = true;
Cấu hình ký tự phân cách có vẻ tốt. Tuy nhiên, "HasFieldsEnclosedInQuotes" là "trò chơi kết thúc". Tôi choáng váng rằng các dấu phân tách có thể được định cấu hình tùy ý, nhưng ngược lại, tôi không có tùy chọn định danh nào khác ngoài các trích dẫn. Hãy nhớ rằng, tôi cần cấu hình trên vòng loại văn bản. Vì vậy, một lần nữa, trừ khi ai đó biết một thủ thuật cấu hình TextFieldParser, đây là trò chơi kết thúc.
OLEDB
Một đồng nghiệp nói với tôi tùy chọn này có hai nhược điểm lớn. Đầu tiên, nó có hiệu suất khủng khiếp đối với các tệp lớn (ví dụ: 10 gig). Thứ hai, vì vậy tôi đã nói, nó đoán các kiểu dữ liệu đầu vào thay vì cho phép bạn chỉ định. Không tốt.
TRỢ GIÚP
Vì vậy, tôi muốn biết sự thật tôi đã sai (nếu có), và các tùy chọn khác mà tôi bỏ qua. Có lẽ ai đó biết một cách để ban giám khảo-rig TextFieldParser sử dụng một dấu phân cách tùy ý. Và có lẽ OLEDB đã giải quyết các vấn đề đã nêu (hoặc có lẽ không bao giờ có chúng?).
Điều gì xảy ra?
Bạn đã thử các tùy chọn được liệt kê tại http://stackoverflow.com/questions/316649/csv-parsing chưa? – TrueWill
Tôi đồng ý với @ Appleman1234, Người trợ giúp phải là tất cả những gì bạn cần – Kane
[Người trợ giúp tệp] (http://www.filehelpers.com/) có đáp ứng các yêu cầu của bạn không? – Appleman1234