Розбийте рядок на масив символьних рядків


113

Мені потрібно розділити String на масив одиночних символів Strings.

Наприклад, розщеплення "кота" дасть масив "c", "a", "t"



3
Як швидка довідка, "" .joine (["c", "a", "t"]), щоб повернути "cat" назад.
шува

2
Можливий дублікат розбиття слів на літери на Java

Java 8: .split("")зробить це.
Amr Lotfy

Відповіді:


120
"cat".split("(?!^)")

Це призведе

масив ["c", "a", "t"]


8
Як і чому? Чи означає це регулярний вираз будь-який символ? Тому що, на мій погляд, з тим, як працює спліт, це повинно розділятися лише на фактичні символи (,?,!, ^ І). Однак це працює так, як ви кажете.
Ty_

3
Це справді вираження виразів, яке називається негативним знаком. Ознайомтесь
Ервін

4
@ EW-CodeMonkey (?!... )- синтаксис регулярного вираження для негативного твердження - він стверджує, що немає відповідності тому, що знаходиться всередині нього. І ^відповідає початку рядка, тому регулярний вираз відповідає всій позиції, яка не є початком рядка, і вставляє там розкол. Цей регулярний вираз також збігається в кінці рядка і тому також додає порожній рядок до результату, за винятком того, що в String.splitдокументації написано, що "остаточні порожні рядки не включаються в результуючий масив".
Боан

8
У Java 8 поведінка String.splitзлегка змінилася, так що провідні порожні рядки, що виробляються збігом нульової ширини, також не включаються в масив результатів, тому (?!^)твердження про те, що позиція не є початком рядка, стає непотрібним, дозволяючи регулярному вираженню бути спрощеним до нічого - "cat".split("")- але в Java 7 і нижче, що створює провідну порожню рядок у масиві результатів.
Боан

1
Він створює масив цілого рядка.
Едуард

109
"cat".toCharArray()

Але якщо вам потрібні струни

"cat".split("")

Редагувати: що поверне порожнє перше значення.


12
"cat" .split ("") повернеться [, c, a, t], ні? У вас буде додатковий персонаж у вашому масиві ...
риф

4
"Cat" .split ("") не працює, як очікував Метт, ви отримаєте додатковий порожній рядок => [, c, a, t].
риф

5
Ця відповідь зараз працює, якщо ви використовуєте Java 8. Див. Stackoverflow.com/a/22718904/1587046
Alexis C.

4
Це було жахливою зміною jdk8, тому що я покладався на спліт ("") і робив обхідні причини цього глупо порожнього першого індексу. Тепер після оновлення до java8, він працює так, як я би очікував цього років тому. на жаль, тепер мій шлях порушує мій код ... ggrrrr.
Марк

@Marc Ви, ймовірно, .toCharArray()все одно користуєтеся ; він уникає регулярного вираження та повертає масив charпримітивів, тому він швидший і легший. Дивно, що вам потрібен масив з 1 символьних рядків .
Боан

41
String str = "cat";
char[] cArray = str.toCharArray();

3
Оригінально запитуючи, початкове запитання задає масив String, а не масив Char. Однак отримати масив String звідси досить просто.
dsolimano

Так, я вже знаю, як отримати масив символів. Я можу просто перебрати через масив char і створити рядок з кожного, хоча іншого способу немає.
Метт

Як би ви перетворили cArrayназад String?
Бітмап

Правильним синтаксисом буде: char [] cArray = str.ToCharArray ();
dbz

6

Якщо символи, що знаходяться за межами базової багатомовної площини , очікуються на вході (деякі символи CJK, нові емоджи ...), такі підходи "a💫b".split("(?!^)")використовувати не можна, оскільки вони розбивають такі символи (результати array ["a", "?", "?", "b"]) і потрібно використовувати щось безпечніше:

"a💫b".codePoints()
    .mapToObj(cp -> new String(Character.toChars(cp)))
    .toArray(size -> new String[size]);

2

Ефективним способом перетворення рядка в масив одно символьних рядків було б це зробити:

String[] res = new String[str.length()];
for (int i = 0; i < str.length(); i++) {
    res[i] = Character.toString(str.charAt(i));
}

Однак це не враховує того факту, що charв a Stringможе насправді представляти половину кодової точки Unicode. (Якщо точка коду відсутня в BMP.) Щоб вирішити це, вам потрібно перебрати кодові точки ... що складніше.

Цей підхід буде швидшим, ніж використання String.split(/* clever regex*/), і, ймовірно, буде швидшим, ніж використання потоків Java 8+. Це швидше, ніж це:

String[] res = new String[str.length()];
int 0 = 0;
for (char ch: str.toCharArray[]) {
    res[i++] = Character.toString(ch);
}  

тому що toCharArrayмає скопіювати символів у новий масив.


2

Підсумовуючи інші відповіді ...

Це працює у всіх версіях Java:

"cat".split("(?!^)")

Це працює лише на Java 8 і вище:

"cat".split("")

0

Можливо, ви можете використовувати цикл for, який проходить через вміст String і витягує символи за символами, використовуючи charAtметод.

У поєднанні з, ArrayList<String>наприклад, ви можете отримати масив окремих символів.


Можливо, ви могли б стати на одній нозі і заспівати "Боже, збережи королеву". Вибачте, але це навіть не близьке до корекції.
Стівен C

0
for(int i=0;i<str.length();i++)
{
System.out.println(str.charAt(i));
}

1
Ви впевнені, що це збирається розділити рядок на масив? Ви просто друкуєте рядок на екрані.
TDG

0

Якщо початковий рядок містить додаткові символи Unicode , він split()не працює, оскільки він розбиває цих символів на сурогатні пари. Щоб правильно поводитися з цими спеціальними символами, працює такий код:

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);
}

0

split("(?!^)")не працює правильно, якщо рядок містить сурогатні пари. Ви повинні використовувати split("(?<=.)").

String[] splitted = "花ab🌹🌺🌷".split("(?<=.)");
System.out.println(Arrays.toString(splitted));

вихід:

[花, a, b, 🌹, 🌺, 🌷]

0

Оператор розповсюдження [ ...] створює масив з кожним символом у рядку:

const cat= 'cat';
const arrayized = [...cat] // ['c', 'a', 't'];

console.log(arrayized);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.