Как и почему? Это регулярное выражение означает любой символ? Потому что, на мой взгляд, с учетом того, как работает split, он должен разбиваться только на фактические символы (,?,!, ^ И). Однако это работает так, как вы говорите.
Ty_ 06
3
Это действительно регулярное выражение, называемое отрицательным просмотром вперед. Ознакомьтесь
Эрвин,
4
@ EW-CodeMonkey (?!... )- это синтаксис регулярного выражения для отрицательного утверждения - он утверждает, что нет совпадения с тем, что внутри него. И ^соответствует началу строки, поэтому регулярное выражение соответствует каждой позиции, которая не является началом строки, и вставляет туда разделение. Это регулярное выражение также совпадает с концом строки и, таким образом, также добавит к результату пустую строку, за исключением того, что в String.splitдокументации сказано, что «завершающие пустые строки не включаются в результирующий массив».
Boann
8
В Java 8 поведение String.splitбыло немного изменено, так что ведущие пустые строки, созданные сопоставлением нулевой ширины, также не включаются в массив результатов, поэтому (?!^)утверждение о том, что позиция не является началом строки, становится ненужным, что позволяет регулярному выражению быть упрощенным до нуля - "cat".split("")но в Java 7 и ниже это создает пустую строку в начале массива результатов.
Это было ужасное изменение в jdk8, потому что я полагался на split ("") и искал обходные пути из-за этого глупого пустого первого индекса. Теперь, после обновления до java8, он работает так, как я ожидал много лет назад. к сожалению, теперь мой обходной путь ломает мой код ... ggrrrr.
Марк
@Marc Вам, вероятно, и так следует использовать .toCharArray(); он избегает регулярных выражений и возвращает массив charпримитивов, поэтому он работает быстрее и легче. Странно нуждаться в массиве строк из 1 символа .
Если при вводе ожидаются символы, выходящие за рамки Basic Multilingual Plane (некоторые символы CJK, новые смайлы ...), такие подходы, как "a💫b".split("(?!^)")нельзя использовать, потому что они разбивают такие символы (приводит к array ["a", "?", "?", "b"]), и необходимо использовать что-то более безопасное:
Эффективным способом преобразования String в массив односимвольных строк было бы следующее:
String[] res =newString[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 =newString[str.length()];int0=0;for(char ch: str.toCharArray[]){
res[i++]=Character.toString(ch);}
потому toCharArrayчто необходимо скопировать символы в новый массив.
Вы уверены, что это разделит строку на массив? Вы просто выводите строку на экран.
TDG
0
Если исходная строка содержит дополнительные символы Unicode , split()это не сработает, поскольку она разбивает эти символы на суррогатные пары. Чтобы правильно обрабатывать эти специальные символы, работает следующий код:
String[] chars =newString[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]=newString(c);
i +=Character.charCount(cp);}
.split("")
сделает это.Ответы:
Это произведет
источник
(?!
...)
- это синтаксис регулярного выражения для отрицательного утверждения - он утверждает, что нет совпадения с тем, что внутри него. И^
соответствует началу строки, поэтому регулярное выражение соответствует каждой позиции, которая не является началом строки, и вставляет туда разделение. Это регулярное выражение также совпадает с концом строки и, таким образом, также добавит к результату пустую строку, за исключением того, что вString.split
документации сказано, что «завершающие пустые строки не включаются в результирующий массив».String.split
было немного изменено, так что ведущие пустые строки, созданные сопоставлением нулевой ширины, также не включаются в массив результатов, поэтому(?!^)
утверждение о том, что позиция не является началом строки, становится ненужным, что позволяет регулярному выражению быть упрощенным до нуля -"cat".split("")
но в Java 7 и ниже это создает пустую строку в начале массива результатов.Но если вам нужны струны
Изменить: который вернет пустое первое значение.
источник
.toCharArray()
; он избегает регулярных выражений и возвращает массивchar
примитивов, поэтому он работает быстрее и легче. Странно нуждаться в массиве строк из 1 символа .источник
cArray
обратно вString
?Если при вводе ожидаются символы, выходящие за рамки Basic Multilingual Plane (некоторые символы CJK, новые смайлы ...), такие подходы, как
"a💫b".split("(?!^)")
нельзя использовать, потому что они разбивают такие символы (приводит кarray ["a", "?", "?", "b"]
), и необходимо использовать что-то более безопасное:источник
Эффективным способом преобразования String в массив односимвольных строк было бы следующее:
Однако при этом не учитывается тот факт, что a
char
в aString
может фактически представлять половину кодовой точки Unicode. (Если кодовая точка отсутствует в BMP.) Чтобы справиться с этим, вам нужно перебирать кодовые точки ... что более сложно.Этот подход будет быстрее, чем использование
String.split(/* clever regex*/)
, и, вероятно, будет быстрее, чем использование потоков Java 8+. Вероятно, быстрее, чем это:потому
toCharArray
что необходимо скопировать символы в новый массив.источник
Подводя итог другим ответам ...
Это работает во всех версиях Java:
Это работает только на Java 8 и выше:
источник
Возможно, вы можете использовать цикл for, который просматривает содержимое String и извлекает символы по символам с помощью
charAt
метода.В сочетании с,
ArrayList<String>
например, вы можете получить массив отдельных символов.источник
источник
Если исходная строка содержит дополнительные символы Unicode ,
split()
это не сработает, поскольку она разбивает эти символы на суррогатные пары. Чтобы правильно обрабатывать эти специальные символы, работает следующий код:источник
split("(?!^)")
работает некорректно, если строка содержит суррогатные пары. Вам следует использоватьsplit("(?<=.)")
.вывод:
источник
Оператор распространения [
...
] создает массив с каждым символом в строке:источник