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.
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 .
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:
String[] res =newString[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 =newString[str.length()];int0=0;for(char ch: str.toCharArray[]){
res[i++]=Character.toString(ch);}
ponieważ toCharArraymusi skopiować znaki do nowej tablicy.
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 =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("")
zrobi to.Odpowiedzi:
To wyprodukuje
źródło
(?!
...)
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, żeString.split
dokumentacja mówi, że „końcowe puste łańcuchy nie są uwzględniane w wynikowej tablicy”.String.split
został 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.Ale jeśli potrzebujesz sznurków
Edycja: która zwróci pustą pierwszą wartość.
źródło
.toCharArray()
; unika wyrażeń regularnych i zwraca tablicęchar
prymitywów, dzięki czemu jest szybsza i lżejsza. To dziwne, że potrzebna jest tablica jednoznakowych ciągów .źródło
cArray
przywróciłString
?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 (skutkujearray ["a", "?", "?", "b"]
) i należy użyć czegoś bezpieczniejszego:źródło
Skutecznym sposobem przekształcenia String w tablicę jednoznakowych Ciągów byłoby zrobienie tego:
Jednak nie uwzględnia to faktu, że a
char
in aString
moż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:ponieważ
toCharArray
musi skopiować znaki do nowej tablicy.źródło
Podsumowując pozostałe odpowiedzi ...
Działa to we wszystkich wersjach Java:
Działa to tylko w Javie 8 i nowszych:
źródło
Może możesz użyć pętli for, która przechodzi przez zawartość String i wyodrębnia znaki po znakach za pomocą
charAt
metody.W połączeniu z
ArrayList<String>
na przykład możesz uzyskać tablicę pojedynczych znaków.źródło
źródło
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:źródło
split("(?!^)")
nie działa poprawnie, jeśli ciąg zawiera pary zastępcze. Powinieneś użyćsplit("(?<=.)")
.wynik:
źródło
Operator spreadu [
...
] tworzy tablicę z każdym znakiem w ciągu:źródło