2013-02-12 36 views
234

Tại sao dòng thứ hai của mã này trong Java ném ArrayIndexOutOfBoundsException?Phân tách chuỗi Java bằng "." (dot)

String filename = "D:/some folder/001.docx"; 
String extensionRemoved = filename.split(".")[0]; 

Trong khi bên dưới hoạt động:

String driveLetter = filename.split("/")[0]; 

tôi sử dụng Java 7.

+1

Không chia sử dụng một chuỗi regex? Trong trường hợp đó "." có nghĩa là bất kỳ nhân vật nào. – Snps

+2

... và đó là dấu gạch chéo ngược DOUBLE để phân tách. – Ben

Trả lời

513

Bạn cần phải thoát khỏi dấu chấm nếu bạn muốn chia trên đen dot:

String extensionRemoved = filename.split("\\.")[0]; 

Nếu không, bạn đang tách trên regex ., có nghĩa là "bất kỳ nhân vật nào".
Lưu ý dấu gạch chéo ngược kép cần thiết để tạo một dấu gạch chéo ngược duy nhất trong regex.


Bạn đang nhận được một ArrayIndexOutOfBoundsException vì chuỗi đầu vào của bạn chỉ là một dấu chấm, tức là ".", đó là một trường hợp cạnh đó tạo ra một mảng trống rỗng khi chia trên chấm; split(regex) loại bỏ tất cả khoảng trống cuối cùng khỏi kết quả, nhưng vì việc tách một dấu chấm trên một chấm chỉ còn hai khoảng trắng, sau khi các khoảng trống ở cuối được xóa, bạn còn lại với một mảng trống.

Để tránh bị ArrayIndexOutOfBoundsException cho trường hợp cạnh này, hãy sử dụng phiên bản quá tải split(regex, limit), có tham số thứ hai là giới hạn kích thước cho mảng kết quả. Khi limittiêu cực, hành vi của loại bỏ khoảng trống dấu từ mảng kết quả bị vô hiệu hóa:

".".split("\\.", -1) // returns an array of two blanks, ie ["", ""] 

tức là, khi filename chỉ là một dấu chấm ".", gọi filename.split("\\.", -1)[0] sẽ trả về một trống, nhưng gọi filename.split("\\.")[0] sẽ ném một ArrayIndexOutOfBoundsException.

+1

Lưu ý rằng tên tệp có thể chứa nhiều dấu chấm. Người ta phải sử dụng chỉ mục cuối cùng của "." và sử dụng nó để tìm chuỗi con của tên tệp. – saurabheights

+0

@saurabheights Câu hỏi không phải là về một regex chính xác, mà là lý do tại sao có một 'ArrayIndexOutOfBoundsException'. Điều đó nói rằng, bạn không chính xác: Bạn không cần phải biết dấu chấm cuối cùng ở đâu; bạn chỉ cần regex đúng: 'filename.split (" \\. (? = [^.] * $) ")'.Điều này sử dụng một * nhìn phía trước * để khẳng định không có dấu chấm ở bất kỳ đâu trong đầu vào theo sau dấu chấm khớp. – Bohemian

28

Điều này là do . là ký tự dành riêng trong biểu thức chính quy, thể hiện bất kỳ ký tự nào. Thay vào đó, chúng tôi nên sử dụng tuyên bố sau:

String extensionRemoved = filename.split("\\.")[0]; 
14

Tôi tin rằng bạn nên thoát khỏi dấu chấm. Thử:

String filename = "D:/some folder/001.docx"; 
String extensionRemoved = filename.split("\\.")[0]; 

Nếu không dấu chấm được hiểu là bất kỳ ký tự nào trong cụm từ thông dụng.

42

"." là một ký tự đặc biệt trong java, vì vậy bạn phải sử dụng "\\". để thoát khỏi nhân vật này:

final String extensionRemoved = filename.split("\\.")[0]; 

Tôi hy vọng điều này sẽ giúp

+4

Nó là _not_ một ký tự đặc biệt trong Java. Đó là một nhân vật đặc biệt trong công cụ regex của Java. –

+0

Tôi không chính xác lắm nhưng tôi đồng ý với bạn. cảm ơn cho độ chính xác;) – aimhaj

+0

Đó là một sự phân biệt đáng làm. Ngoài ra, tôi chỉ nhận ra rằng tôi đã sai lầm một chút; nó là một char đặc biệt trong Java, nhưng đó không phải là lý do tại sao nó gây ra một vấn đề ở đây. Dù sao. –

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