2013-05-25 29 views
8

Tôi đang xử lý một dòng nhất định được đọc từ tệp .csv sử dụng String.split(",") và tìm chuỗi trống cuối cùng sau dấu phân tách cuối cùng không làm cho nó vào mảng được tạo bởi hàm split.Khi xử lý chuỗi csv có trường cuối cùng trống, myString.split (",") trả về số lượng mục nhập không chính xác

Dưới đây là các giá trị biến được gây ra lỗi:

String toSplit = "1,Some Value,31337,Another Value,"; 
String[] values = toSplit.split(","); 

Mảng values kết thúc lên có ít hơn số lượng dự kiến ​​các mục mảng. Mảng được tạo là:

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 

với một values[4] ném ArrayIndexOutOfBounds ngoại lệ.

Mảng tôi muốn là:

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 

Một caveat: Tôi đọc đầu ra của một người sáng tạo tệp .csv và không muốn sử dụng delimiters chuỗi hoặc ném một '' nhân vật khoảng trắng vào nơi dữ liệu trống. (ví dụ: không muốn: toSplit = "1,Some Value,31337,Another Value, " có khoảng trắng ở cuối.)

Đây có phải là lỗi trong String.split() và có tùy chọn giải pháp khác không?

Trả lời

13

Đã phát hiện ra khi tôi đang nhập câu hỏi! Sử dụng stringObj.split (",", numDelimitersExpected) hoặc, như @Supericy đã chỉ ra, stringObj.split (",", -1).

Theo các tài liệu Android về stringObj.split(delimiter) một cuộc gọi đến line.split(",") là tương đương với một cuộc gọi đến line.split(",", 0) với đối số thứ hai đề cập đến limit, thiết lập 'số lượng tối đa các mục' và xác định 'điều trị trailing trống chuỗi '. Nhìn vào tài liệu cho stringObj.split(delimiter), nó tuyên bố rằng với limit == 0 'các chuỗi trống sẽ không được trả lại'.

Các giải pháp là sử dụng một cuộc gọi đến split(",", limit) với limit bộ với số các mục mảng bạn mong đợi để lấy lại. Trong trường hợp của tôi, giới hạn được đặt thành 5 trả về mảng

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 

chính xác là những gì tôi muốn. Sự cố được giải quyết.

Trong thực tế, ngay cả khi chuỗi toSplit của bạn có delimiters ít hơn limit, một cuộc gọi với một bộ limit sẽ vẫn tạo mục mảng trống lên đến limit. Ví dụ, với chuỗi đầu vào tương tự như trong câu hỏi của tôi:

String toSplit = "1,Some Value,31337,Another Value," 

một cuộc gọi String values[] = toSplit.split(",", 8) lợi nhuận mảng

values[0] : '1' 
values[1] : 'Some Value' 
values[2] : '31337' 
values[3] : 'Another Value' 
values[4] : '' 
values[5] : '' 
values[6] : '' 
values[7] : '' 

gọn gàng!

Lưu ý: Java String.split(delimiter) của Oracle có cùng chức năng với tài liệu Android giành giải thích ngắn gọn hơn. (:

Edit: Theo @Supericy thêm, toSplit.split(",", -1) sẽ cũng đúng cách trả lại entry trống trailing Cám ơn sự bổ sung

+0

Trong vòng một phút các câu hỏi và câu trả lời có mặt:.! D – Lion

+2

Ngoài ra, bạn có thể sử dụng 'String.split (delimiter, -1)' nếu bạn không biết số lượng các mục trước thời hạn, javadoc * làm * cho bạn biết rằng nó đang gọi 'String.split (del, limit)' – Supericy

+0

@Supericy: Cuộc gọi tốt với giới hạn -1 Và có, tôi đã đọc rằng các tài liệu Oracle giải thích rằng chức năng là tốt, nhưng các tài liệu Android sử dụng về đóng gói chức năng nói chính xác như nhau điều như tài liệu Oracle nhưng ngắn gọn hơn. Lưu ý: Tôi đã không nêu tài liệu sai, chỉ là nó ít ngắn gọn hơn. Cả hai đều hoàn thành. Một là cả hai hoàn thành và cũng ngắn hơn, do đó nó thắng. (: Cảm ơn vì đầu vào của bạn! – reor

Các vấn đề liên quan