Podziel ciąg na tablicę ciągów znaków

Odpowiedzi:

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

To wyprodukuje

tablica ["c", "a", "t"]

coberty
źródło
8
Jak i dlaczego? Czy to wyrażenie regularne oznacza dowolną postać? Ponieważ moim zdaniem, zgodnie ze sposobem, w jaki działa rozdzielanie, powinno to obejmować tylko rzeczywiste znaki (,?,!, ^ I). Jednak działa tak, jak mówisz.
Ty_
3
To jest rzeczywiście wyrażenie regularne, zwane negatywnym wyprzedzeniem. Sprawdź
Erwin
4
@ EW-CodeMonkey (?!... )to składnia wyrażenia regularnego dla twierdzenia negatywnego - zapewnia, że ​​nie ma dopasowania tego, co jest w środku. I ^dopasowuje początek łańcucha, więc wyrażenie regularne dopasowuje się w każdej pozycji, która nie jest początkiem ciągu, i wstawia tam podział. To wyrażenie regularne również pasuje na końcu łańcucha, więc do wyniku dołączy również pusty ciąg, z wyjątkiem tego, że String.splitdokumentacja mówi, że „końcowe puste łańcuchy nie są uwzględniane w wynikowej tablicy”.
Boann
8
W Javie 8 zachowanie String.splitzostał nieznacznie zmieniony tak, że prowadząc pustych strun produkowanych przez zerowej szerokości meczu także nie są zawarte w tablicy wyników, więc (?!^)twierdzenie, że pozycja nie jest początkiem łańcucha staje się zbędne, umożliwiając regex być uproszczone do zera - "cat".split("")- ale w Javie 7 i niższych generuje początkowy pusty ciąg w tablicy wyników.
Boann
1
Tworzy tablicę całego ciągu.
Eduard,
109
"cat".toCharArray()

Ale jeśli potrzebujesz sznurków

"cat".split("")

Edycja: która zwróci pustą pierwszą wartość.

Yuriy Faktorovich
źródło
12
„cat” .split („”) zwróci [, c, a, t], no? Będziesz miał dodatkową postać w swojej Array ...
rafa
4
„Cat” .split („”) nie działa zgodnie z oczekiwaniami Matta, otrzymasz dodatkowy pusty String => [, c, a, t].
rafa
5
Ta odpowiedź działa teraz, jeśli używasz języka Java 8. Zobacz stackoverflow.com/a/22718904/1587046
Alexis C.
4
To była przerażająca zmiana w jdk8, ponieważ polegałem na splicie ("") i zastosowałem obejście tego głupiego, pustego pierwszego indeksu. Teraz, po aktualizacji do java8, działa tak, jak bym się tego spodziewał lata temu. niestety teraz moje obejście psuje mój kod ... ggrrrr.
Marc
@Marc I tak prawdopodobnie powinieneś używać .toCharArray(); unika wyrażeń regularnych i zwraca tablicę charprymitywów, dzięki czemu jest szybsza i lżejsza. To dziwne, że potrzebna jest tablica jednoznakowych ciągów .
Boann
41
String str = "cat";
char[] cArray = str.toCharArray();
Ramana
źródło
3
Nitpicking, pierwotne pytanie dotyczy tablicy String, a nie tablicy Char. Jednak dość łatwo jest uzyskać stąd tablicę String.
dsolimano
Tak, już wiem, jak uzyskać tablicę znaków. Mogę po prostu przejść przez tablicę znaków i utworzyć ciąg z każdego z nich, jeśli nie ma innego sposobu.
Matt
Jak byś cArrayprzywrócił String?
Bitmap
Prawidłowa składnia to: char [] cArray = str.ToCharArray ();
dbz
6

Jeśli na wejściu spodziewane są postacie spoza Basic Multilingual Plane (niektóre postacie CJK, nowe emoji ...), "a💫b".split("(?!^)")nie można zastosować podejść takich jak , ponieważ łamią takie znaki (skutkuje array ["a", "?", "?", "b"]) i należy użyć czegoś bezpieczniejszego:

"a💫b".codePoints()
    .mapToObj(cp -> new String(Character.toChars(cp)))
    .toArray(size -> new String[size]);
Jan Molnar
źródło
2

Skutecznym sposobem przekształcenia String w tablicę jednoznakowych Ciągów byłoby zrobienie tego:

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

Jednak nie uwzględnia to faktu, że a charin a Stringmoże w rzeczywistości reprezentować połowę punktu kodowego Unicode. (Jeśli punkt kodowy nie znajduje się w BMP.) Aby sobie z tym poradzić, musisz iterować przez punkty kodowe ... co jest bardziej skomplikowane.

To podejście będzie szybsze niż używanie String.split(/* clever regex*/)i prawdopodobnie będzie szybsze niż używanie strumieni Java 8+. Prawdopodobnie szybciej niż to:

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

ponieważ toCharArraymusi skopiować znaki do nowej tablicy.

Stephen C.
źródło
2

Podsumowując pozostałe odpowiedzi ...

Działa to we wszystkich wersjach Java:

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

Działa to tylko w Javie 8 i nowszych:

"cat".split("")
Lezorte
źródło
0

Może możesz użyć pętli for, która przechodzi przez zawartość String i wyodrębnia znaki po znakach za pomocą charAtmetody.

W połączeniu z ArrayList<String>na przykład możesz uzyskać tablicę pojedynczych znaków.

rafa
źródło
Może mógłbyś stanąć na jednej nodze i zaśpiewać „God Save the Queen”. Przepraszamy, ale to nie jest nawet bliskie poprawności.
Stephen C
0
for(int i=0;i<str.length();i++)
{
System.out.println(str.charAt(i));
}
JV Więcej
źródło
1
Czy na pewno spowoduje to podzielenie ciągu na tablicę? Po prostu drukujesz napis na ekranie.
TDG,
0

Jeśli oryginalny ciąg zawiera dodatkowe znaki Unicode , split()nie zadziała, ponieważ dzieli te znaki na pary zastępcze. Aby poprawnie obsługiwać te znaki specjalne, działa taki kod:

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);
}
Daniel Nitzan
źródło
0

split("(?!^)")nie działa poprawnie, jeśli ciąg zawiera pary zastępcze. Powinieneś użyć split("(?<=.)").

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

wynik:

[花, a, b, 🌹, 🌺, 🌷]
saka1029
źródło
0

Operator spreadu [ ...] tworzy tablicę z każdym znakiem w ciągu:

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

console.log(arrayized);

MHS
źródło