Разделить строку на массив символьных строк


114

Мне нужно разбить строку на массив односимвольных строк.

Например, разделение «кот» даст массив «c», «a», «t»



3
В качестве краткой справки: "" .join (["c", "a", "t"]), чтобы вернуть "cat".
шува

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

Java 8: .split("")сделает это.
Амр Лотфи

Ответы:


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

Это произведет

array ["c", "a", "t"]


8
Как и почему? Это регулярное выражение означает любой символ? Потому что, на мой взгляд, с учетом того, как работает split, он должен разбиваться только на фактические символы (,?,!, ^ И). Однако это работает так, как вы говорите.
Ty_ 06

3
Это действительно регулярное выражение, называемое отрицательным просмотром вперед. Ознакомьтесь
Эрвин,

4
@ EW-CodeMonkey (?!... )- это синтаксис регулярного выражения для отрицательного утверждения - он утверждает, что нет совпадения с тем, что внутри него. И ^соответствует началу строки, поэтому регулярное выражение соответствует каждой позиции, которая не является началом строки, и вставляет туда разделение. Это регулярное выражение также совпадает с концом строки и, таким образом, также добавит к результату пустую строку, за исключением того, что в String.splitдокументации сказано, что «завершающие пустые строки не включаются в результирующий массив».
Boann

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

1
Он создает массив из всей строки.
Эдуард

109
"cat".toCharArray()

Но если вам нужны струны

"cat".split("")

Изменить: который вернет пустое первое значение.


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

4
"Cat" .split ("") работает не так, как ожидал Мэтт, вы получите дополнительную пустую строку => [, c, a, t].
reef

5
Этот ответ теперь работает, если вы используете Java 8. См. Stackoverflow.com/a/22718904/1587046
Alexis C.

4
Это было ужасное изменение в jdk8, потому что я полагался на split ("") и искал обходные пути из-за этого глупого пустого первого индекса. Теперь, после обновления до java8, он работает так, как я ожидал много лет назад. к сожалению, теперь мой обходной путь ломает мой код ... ggrrrr.
Марк

@Marc Вам, вероятно, и так следует использовать .toCharArray(); он избегает регулярных выражений и возвращает массив charпримитивов, поэтому он работает быстрее и легче. Странно нуждаться в массиве строк из 1 символа .
Boann

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

3
Nitpicking, исходный вопрос запрашивает массив String, а не массив Char. Однако отсюда довольно легко получить массив String.
dsolimano 08

Да, я уже знаю, как получить массив символов. Я могу просто перебрать массив char и создать строку из каждого, если нет другого пути.
Мэтт

Как бы вы преобразовали cArrayобратно в String?
Bitmap

Правильный синтаксис: char [] cArray = str.ToCharArray ();
dbz

6

Если при вводе ожидаются символы, выходящие за рамки Basic Multilingual Plane (некоторые символы CJK, новые смайлы ...), такие подходы, как "a💫b".split("(?!^)")нельзя использовать, потому что они разбивают такие символы (приводит к array ["a", "?", "?", "b"]), и необходимо использовать что-то более безопасное:

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

2

Эффективным способом преобразования String в массив односимвольных строк было бы следующее:

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

Однако при этом не учитывается тот факт, что a 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>например, вы можете получить массив отдельных символов.


Может, стоит на одной ноге спеть «Боже, храни королеву». Извините, но это даже близко не к правильному.
Stephen 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.