Jak podzielić ciąg "Thequickbrownfoxjumps"
na podciągi o równej wielkości w Javie. Na przykład. "Thequickbrownfoxjumps"
4 równych rozmiarów powinno dać wynik.
["Theq","uick","brow","nfox","jump","s"]
Podobne pytanie:
Jak podzielić ciąg "Thequickbrownfoxjumps"
na podciągi o równej wielkości w Javie. Na przykład. "Thequickbrownfoxjumps"
4 równych rozmiarów powinno dać wynik.
["Theq","uick","brow","nfox","jump","s"]
Podobne pytanie:
Odpowiedzi:
Oto jednowierszowa wersja wyrażenia regularnego:
\G
jest asercją o zerowej szerokości, która pasuje do pozycji, w której zakończyło się poprzednie dopasowanie. Jeśli nie było poprzedniego dopasowania, dopasowuje początek wejścia, tak samo jak\A
. Obejmujący lookbehind dopasowuje pozycję, która jest cztery znaki dalej od końca ostatniego dopasowania.Zarówno lookbehind, jak i
\G
zaawansowane funkcje regex, nie są obsługiwane przez wszystkie odmiany . Co więcej,\G
nie jest konsekwentnie wdrażany we wszystkich smakach, które go obsługują. Ta sztuczka zadziała (na przykład) w Javie , Perlu, .NET i JGSoft, ale nie w PHP (PCRE), Ruby 1.9+ lub TextMate (oba Oniguruma). JavaScript/y
(flaga sticky) nie jest tak elastyczna jak\G
i nie mogłaby być używana w ten sposób, nawet gdyby JS obsługiwał lookbehind.Powinienem wspomnieć, że niekoniecznie polecam to rozwiązanie, jeśli masz inne opcje. Rozwiązania inne niż wyrażenia regularne w innych odpowiedziach mogą być dłuższe, ale są też samodokumentujące; ten jest po prostu przeciwieństwem tego. ;)
Ponadto to nie działa w systemie Android, który nie obsługuje użycia
\G
w lookbehinds.źródło
String.substring()
zamiast wyrażenia regularnego, wymagające kilku dodatkowych linii kodu, będzie działać gdzieś 5x szybciej ...(?s)
w regex:(?s)(?<=\\G.{4})
.java.util.regex.PatternSyntaxException: Look-behind pattern matches must have a bounded maximum length
Cóż, dość łatwo jest to zrobić za pomocą prostych operacji arytmetycznych i na łańcuchach znaków:
Myślę, że nie warto używać do tego wyrażenia regularnego.
EDYCJA: Moje uzasadnienie dla nieużywania wyrażenia regularnego:
źródło
Splitter.fixedLength(4)
poleciłbym guawę zgodnie z sugestią seanizera.Z Google Guava jest to bardzo łatwe :
Wynik:
Lub jeśli potrzebujesz wyniku jako tablicy, możesz użyć tego kodu:
Odniesienie:
Splitter.fixedLength()
Splitter.split()
Iterables.toArray()
Uwaga: konstrukcja rozdzielacza jest pokazana w wierszu powyżej, ale ponieważ rozdzielacze są niezmienne i wielokrotnego użytku, dobrą praktyką jest przechowywanie ich w stałych:
źródło
String.join(separator, arrayOrCollection)
Jeśli używasz bibliotek ogólnego przeznaczenia Google guava (i szczerze mówiąc, każdy nowy projekt Java prawdopodobnie powinien ), jest to niesamowicie trywialne w przypadku klasy Splitter :
i to wszystko . Proste jak!
źródło
źródło
src.length()
ilen
są obaint
, twoje wywołanieceiling
nie spełnia tego, czego chcesz - sprawdź, jak robią to niektóre inne odpowiedzi: (src.length () + len - 1) / lenźródło
for
pętlom?for
Pętla jest rzeczywiście bardziej „naturalny” Zastosowanie wyborem dla tego :-) Dzięki za wskazanie tego.Możesz użyć
substring
fromString.class
(obsługa wyjątków) lub z Apache lang commons (obsługuje wyjątki za Ciebie)Umieść go w pętli i gotowe.
źródło
substring
metodą wString
klasie standardowej ?Wolę to proste rozwiązanie:
źródło
substring
implementacja zmieniła się wraz z Javą 7, aktualizacją 6 w połowie 2012 roku, kiedy polaoffset
icount
zostały usunięte zString
klasy. Tak więc złożonośćsubstring
zmieniła się w liniową na długo przed udzieleniem tej odpowiedzi. Ale dla małej struny, takiej jak na przykładzie, nadal działa wystarczająco szybko, a dla dłuższych ... cóż, to zadanie rzadko występuje w praktyce.Oto implementacja z jedną linijką przy użyciu strumieni Java8:
Daje następujący wynik:
źródło
String[] result = IntStream.range(0, (input.length()+3)/4) .mapToObj(i -> input.substring(i *= 4, Math.min(i + 4, input.length()))) .toArray(String[]::new);
Oto jeden-liner wersja wykorzystująca Java 8 IntStream określić indeksy początków plastrów:
źródło
Jeśli chcesz podzielić ciąg równo do tyłu, tj. Od prawej do lewej, na przykład, aby podzielić
1010001111
na[10, 1000, 1111]
, oto kod:źródło
używam następującego rozwiązania java 8:
źródło
Java 8 rozwiązanie (jak to ale nieco prostsze):
źródło
Zapytałem @Alan Moore w komentarzu do przyjętego rozwiązania jaki sposób można obsługiwać ciągi znaków z nowymi . Zasugerował użycie DOTALL.
Korzystając z jego sugestii, stworzyłem małą próbkę tego, jak to działa:
Ale podoba mi się również rozwiązanie @Jon Skeets w https://stackoverflow.com/a/3760193/1237974 . Aby zapewnić łatwość obsługi w większych projektach, w których nie wszyscy są jednakowo doświadczeni w wyrażeniach regularnych, prawdopodobnie użyłbym rozwiązania Jons.
źródło
Innym rozwiązaniem brutalnej siły może być:
Gdzie kod po prostu przechodzi przez ciąg z podciągami
źródło
Wynik
źródło
źródło
Oto moja wersja oparta na strumieniach RegEx i Java 8. Warto wspomnieć, że
Matcher.results()
metoda jest dostępna od wersji Java 9.Zawiera test.
źródło
źródło
źródło