Phân tách chuỗi Java đã loại bỏ các giá trị trống


286

Tôi đang cố gắng phân tách Giá trị bằng cách sử dụng dấu phân cách. Nhưng tôi đang tìm thấy kết quả đáng ngạc nhiên

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

Tôi đang mong đợi để có được 8 giá trị. [5,6,7, EMPTY, 8,9, EMPTY, EMPTY] Nhưng tôi chỉ nhận được 6 giá trị.

Bất kỳ ý tưởng và làm thế nào để sửa chữa. Không có vấn đề giá trị EMPTY đến bất cứ nơi nào, nó nên ở trong mảng.

Câu trả lời:


492

split(delimiter)theo mặc định loại bỏ các chuỗi rỗng theo sau khỏi mảng kết quả. Để tắt cơ chế này, chúng ta cần sử dụng phiên bản quá tải split(delimiter, limit)với limitcài đặt thành giá trị âm như

String[] split = data.split("\\|", -1);

Thêm chi tiết:
split(regex)trả về nội bộ kết quả split(regex, 0)và trong tài liệu của phương pháp này bạn có thể tìm thấy (nhấn mạnh của tôi)

Các limitthông số kiểm soát số lần mô hình được áp dụng và do đó ảnh hưởng đến chiều dài của mảng kết quả.

Nếu giới hạn nlớn hơn không thì mô hình sẽ được áp dụng tại hầu hết các n - 1 lần, chiều dài của mảng sẽ không lớn hơn n, và mục cuối cùng của mảng sẽ chứa tất cả đầu vào vượt quá delimiter phù hợp cuối cùng.

Nếu nkhông tích cực sau đó mô hình sẽ được áp dụng nhiều lần càng tốt và mảng có thể có bất kỳ chiều dài.

Nếu nsố không sau đó mô hình sẽ được áp dụng nhiều lần càng tốt, mảng có thể có bất kỳ chiều dài, và trailing chuỗi rỗng sẽ bị loại bỏ .

Ngoại lệ :

Điều đáng nói là việc loại bỏ chuỗi rỗng theo sau chỉ có ý nghĩa nếu kho chuỗi trống đó được tạo bởi cơ chế phân tách . Vì vậy, "".split(anything)vì chúng ta không thể phân chia ""xa hơn, chúng ta sẽ nhận được [""]mảng kết quả .
Nó xảy ra bởi vì sự phân tách đã không xảy ra ở đây, vì vậy ""mặc dù trống và dấu vết đại diện cho chuỗi gốc , không phải chuỗi trống được tạo bởi quá trình phân tách.


2
ồ Điều đó đã làm việc tuyệt vời. Nhưng -1 điều này thay đổi mọi thứ như thế nào?
Reddy

1
bạn thậm chí có thể thử vớidata.split("\\|", 8)
Subhrajyoti Majumder

23
Đừng sử dụng split("\\|", 8)vì giới hạn này đối với tám mã thông báo đầu tiên! Nếu chuỗi của bạn là biến, bạn nên sử dụng split("\\|", -1)để nó tạo ra số lượng mã thông báo không giới hạn và không loại bỏ mã thông báo trống ở cuối.
ADTC

2
@Reddy -1 ( hoặc bất kỳ số âm nào trong thực tế, không quan trọng giá trị tuyệt đối là gì ) cho biết phương thức phân tách để giữ các mã thông báo trống ở cuối. Mặc định là 0, cho biết phương thức loại bỏ các mã thông báo trống ở cuối mảng.
ADTC

8
Rõ ràng, rất nhiều người mong đợi rằng việc giữ các chuỗi trống ở cuối là chức năng mặc định split(regex). Họ đã kết thúc ở đây và phát hiện ra rằng nó không phải là.
Attila Tanyi

32

Từ các tài liệu của String.split(String regex):

Phương thức này hoạt động như thể bằng cách gọi phương thức phân chia hai đối số với biểu thức đã cho và đối số giới hạn bằng không. Do đó, chuỗi triling rỗng không được bao gồm trong mảng kết quả.

Vì vậy, bạn sẽ phải sử dụng hai phiên bản đối số String.split(String regex, int limit)có giá trị âm:

String[] split = data.split("\\|",-1);

Bác sĩ:

Nếu giới hạn n lớn hơn 0 thì mẫu sẽ được áp dụng tối đa n - 1 lần, độ dài của mảng sẽ không lớn hơn n và mục nhập cuối cùng của mảng sẽ chứa tất cả đầu vào ngoài dấu phân cách khớp cuối cùng. Nếu n không dương thì mẫu sẽ được áp dụng nhiều lần nhất có thể và mảng có thể có độ dài bất kỳ. Nếu n bằng 0 thì mẫu sẽ được áp dụng nhiều lần nhất có thể, mảng có thể có bất kỳ độ dài nào và các chuỗi rỗng kéo dài sẽ bị loại bỏ.

Điều này sẽ không bỏ qua bất kỳ yếu tố trống, bao gồm cả các yếu tố dấu.


4

Từ API String.split () :

Chia chuỗi này xung quanh các kết quả khớp của biểu thức chính quy định. Phương thức này hoạt động như thể bằng cách gọi phương thức phân tách hai đối số với biểu thức đã cho và đối số giới hạn bằng không. Do đó, chuỗi triling rỗng không được bao gồm trong mảng kết quả.

Quá tải String.split (regex, int) phù hợp hơn cho trường hợp của bạn.


1
Điều đó giải thích hành vi nhưng không trả lời câu hỏi.
assylias

@assylias đã thêm nó vào câu trả lời của tôi ngay bây giờ :)
PermGenError

4

String[] split = data.split("\\|",-1);

Đây không phải là yêu cầu thực tế trong tất cả các thời gian. Nhược điểm ở trên được hiển thị dưới đây:

Scenerio 1:
When all data are present:
    String data = "5|6|7||8|9|10|";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 7
    System.out.println(splt.length); //output: 8

Khi dữ liệu bị thiếu:

Scenerio 2: Data Missing
    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output: 8

Yêu cầu thực sự là độ dài nên là 7 mặc dù thiếu dữ liệu. Bởi vì có những trường hợp như khi tôi cần chèn vào cơ sở dữ liệu hoặc cái gì khác. Chúng ta có thể đạt được điều này bằng cách sử dụng phương pháp dưới đây.

    String data = "5|6|7||8|||";
    String[] split = data.split("\\|");
    String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
    System.out.println(split.length); //output: 5
    System.out.println(splt.length); //output:7

Những gì tôi đã làm ở đây là, tôi đang xóa "|" ống ở cuối và sau đó tách Chuỗi. Nếu bạn có "," với tư cách là người tách biệt thì bạn cần thêm ", $" vào bên trong thay thế.


1

bạn có thể có nhiều dấu phân cách, bao gồm các ký tự khoảng trắng, dấu phẩy, dấu chấm phẩy, v.v., hãy lấy những ký tự trong nhóm lặp lại với [] +, như:

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

bạn sẽ có 4 mã thông báo - a, b, c, d

các dấu tách hàng đầu trong chuỗi nguồn cần được loại bỏ trước khi áp dụng phân tách này.

như câu trả lời cho câu hỏi:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

khoảng trắng được thêm vào chỉ trong trường hợp nếu bạn có những dấu phân cách cùng với |

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.