Tôi cần chia một Chuỗi thành một mảng Chuỗi ký tự đơn.
Ví dụ: tách "cat" sẽ cho ra mảng "c", "a", "t"
.split("")
sẽ làm được.
Tôi cần chia một Chuỗi thành một mảng Chuỗi ký tự đơn.
Ví dụ: tách "cat" sẽ cho ra mảng "c", "a", "t"
.split("")
sẽ làm được.
Câu trả lời:
"cat".split("(?!^)")
Điều này sẽ tạo ra
mảng ["c", "a", "t"]
(?!
... )
là cú pháp regex cho một khẳng định phủ định - nó khẳng định rằng không có sự khớp với những gì bên trong nó. Và ^
khớp với phần đầu của chuỗi, do đó, regex khớp ở mọi vị trí không phải là phần đầu của chuỗi và chèn một phần tách ở đó. Regex này cũng khớp ở cuối chuỗi và do đó cũng sẽ nối một chuỗi trống vào kết quả, ngoại trừ String.split
tài liệu cho biết "các chuỗi trống theo sau không được bao gồm trong mảng kết quả".
String.split
đã được thay đổi một chút để các chuỗi trống dẫn đầu được tạo ra bởi một kết quả có độ rộng bằng 0 cũng không được bao gồm trong mảng kết quả, do đó, việc (?!^)
khẳng định rằng vị trí không phải là đầu của chuỗi trở nên không cần thiết, cho phép regex được đơn giản hóa thành không có gì - "cat".split("")
- nhưng trong Java 7 trở xuống tạo ra một chuỗi trống ở đầu trong mảng kết quả.
"cat".toCharArray()
Nhưng nếu bạn cần chuỗi
"cat".split("")
Chỉnh sửa: sẽ trả về giá trị đầu tiên trống.
.toCharArray()
Dù sao thì bạn cũng nên sử dụng ; nó tránh regex và trả về một mảng char
nguyên thủy để nó nhanh hơn và nhẹ hơn. Thật kỳ lạ khi cần một mảng chuỗi 1 ký tự .
String str = "cat";
char[] cArray = str.toCharArray();
cArray
trở lại String
?
Nếu các ký tự ngoài Mặt phẳng đa ngôn ngữ cơ bản được mong đợi khi nhập (một số ký tự CJK, biểu tượng cảm xúc mới ...), thì "a💫b".split("(?!^)")
không thể sử dụng các phương pháp như vậy , vì chúng ngắt các ký tự như vậy (kết quả thành array ["a", "?", "?", "b"]
) và phải sử dụng thứ gì đó an toàn hơn:
"a💫b".codePoints()
.mapToObj(cp -> new String(Character.toChars(cp)))
.toArray(size -> new String[size]);
Một cách hiệu quả để biến một Chuỗi thành một mảng các Chuỗi một ký tự là thực hiện điều này:
String[] res = new String[str.length()];
for (int i = 0; i < str.length(); i++) {
res[i] = Character.toString(str.charAt(i));
}
Tuy nhiên, điều này không tính đến thực tế là một char
trong một String
thực sự có thể đại diện cho một nửa điểm mã Unicode. (Nếu điểm mã không có trong BMP.) Để giải quyết điều đó, bạn cần phải lặp lại các điểm mã ... điều này phức tạp hơn.
Cách tiếp cận này sẽ nhanh hơn so với sử dụng String.split(/* clever regex*/)
và có thể sẽ nhanh hơn so với sử dụng các luồng Java 8+. Nó có thể nhanh hơn thế này:
String[] res = new String[str.length()];
int 0 = 0;
for (char ch: str.toCharArray[]) {
res[i++] = Character.toString(ch);
}
bởi vì toCharArray
phải sao chép các ký tự vào một mảng mới.
Có thể bạn có thể sử dụng một vòng lặp for đi qua nội dung Chuỗi và trích xuất các ký tự theo các ký tự bằng charAt
phương pháp này.
Kết hợp với một ArrayList<String>
ví dụ, bạn có thể nhận được mảng các ký tự riêng lẻ của mình.
Nếu chuỗi ban đầu chứa các ký tự Unicode bổ sung thì split()
sẽ không hoạt động vì nó chia các ký tự này thành các cặp thay thế. Để xử lý chính xác các ký tự đặc biệt này, một mã như thế này hoạt động:
String[] chars = new String[stringToSplit.codePointCount(0, stringToSplit.length())];
for (int i = 0, j = 0; i < stringToSplit.length(); j++) {
int cp = stringToSplit.codePointAt(i);
char c[] = Character.toChars(cp);
chars[j] = new String(c);
i += Character.charCount(cp);
}