Użyj String.split () z wieloma ogranicznikami


201

Muszę podzielić ciąg znaków na separator -i .. Poniżej znajdują się moje pożądane wyniki.

AA.BB-CC-DD.zip ->

AA
BB
CC
DD
zip 

ale mój poniższy kod nie działa.

private void getId(String pdfName){
    String[]tokens = pdfName.split("-\\.");
}

Na podstawie tego, co powiedziałeś, wygląda na to, że działa dobrze. Jaka jest twoja pożądana wydajność?
— Jeff

2
@Jeff: Pokazał swoją pożądaną wydajność ( AA/ BB/ CC...)
— TJ Crowder

2
Jesteś pewny? Zinterpretowałem to jako jego bieżącą moc wyjściową, a nie jego pożądaną moc wyjściową. Może nadszedł czas, aby wstać i trochę spacerować.
— Jeff

@Jeff: Przepraszam za zamieszanie, zaktualizowałem swój post, aby wyjaśnić twoje nieporozumienie.
— Thang Pham

Regex obniży Twoją wydajność. Poleciłbym napisać metodę, która będzie przechodzić znak po znaku i w razie potrzeby dzieli ciąg. Możesz zoptymalizować to później, aby uzyskać wydajność log (n).
— Princesh

Odpowiedzi:


311

Myślę, że musisz dołączyć operator wyrażenia regularnego OR :

String[]tokens = pdfName.split("-|\\.");

To, co masz, będzie pasować:
[DASH, a następnie DOT razem] -.
nie
[DASH lub DOT żaden z nich] -lub.


9
dlaczego potrzebujemy dwóch odwrotnych ukośników?
— pjain

7
.Znaków w wyrażeniu regularnym oznacza dowolny znak inny niż nowej linii. tutorialspoint.com/java/java_regular_expressions.htm W tym przypadku jednak chcieli rzeczywistej postaci .. Dwa odwrotne ukośniki oznaczają, że masz na myśli .. Ukośnik odwrotny jest znakiem ucieczki.
— Monkeygrinder

2
w normalnych przypadkach byłoby .split("match1|match2")(np. split("https|http")), \\ jest uniknięcie specjalnego znaku .w powyższym przypadku
— prayagupd

lub ogólnie możesz użyć pdfName.split("\\W");poniższej odpowiedzi
— @Peter Knego

1
użyj [-.]zamiast-|\\.
— Saeed

49

Spróbuj tego wyrażenia regularnego "[-.]+". Znak + traktuje kolejne znaki separatora jako jeden. Usuń plus, jeśli nie chcesz tego.


8
@Lurkers: Jedynym powodem, dla którego Peter nie musiał uciekać, -było to, że jest to pierwsza myśl w środku [], w przeciwnym razie musiałby wystąpić odwrotny ukośnik przed nim (i oczywiście, aby umieścić odwrotny ukośnik przed nim, my potrzeba dwóch, ponieważ jest to literał łańcuchowy).
— TJ Crowder

Myślę, że ta odpowiedź jest lepsza niż zaakceptowana, ponieważ gdy używasz operatora logicznego, problem polega na tym, że jeden z twoich ograniczników może być częścią twoich „tokenów” wyników. Nie stanie się tak w przypadku [-.] +
— Jacka

26

Możesz użyć wyrażenia regularnego „\ W”. Pasuje do dowolnego nie-wyrazowego znaku. Wymagany wiersz to:

String[] tokens=pdfName.split("\\W");

to nie działa dla mnie `String s =" id (INT), name (STRING), ". Użycie \\ W tutaj tworzy tablicę o długości 6, gdzie jak powinno być tylko 4
— użytkownik3527975

2
Spowoduje to również uszkodzenie, gdy dane wejściowe zawierają znak Unicode. Najlepiej dołączyć tylko rzeczywisty ogranicznik, zamiast „grab all” z \W.
— nhahtdh,

13

Podany ciąg split jest formą wyrażenia regularnego, więc:

private void getId(String pdfName){
    String[]tokens = pdfName.split("[\\-.]");
}

Oznacza to podział na dowolną postać w [](musimy uciec -z odwrotnym ukośnikiem, ponieważ jest on wewnątrz wyjątkowy []; i oczywiście musimy uciec z odwrotnego ukośnika, ponieważ jest to ciąg znaków). (Przeciwnie, .jest zwykle wyjątkowy, ale nie jest wyjątkowy w środku []).


W tym przypadku nie musisz uciekać od łącznika, ponieważ [-.]nie można go interpretować jako zakresu.
— Alan Moore

1
@Alan: Ponieważ to pierwsza rzecz w klasie, to całkiem prawda. Ale zawsze to robię, zbyt łatwo jest wrócić później i dodać coś bez zastanowienia. Ucieczka to nic nie kosztuje, więc ...
— TJ Crowder

Czy wiesz, jak uciec od nawiasów? Mam ciąg „[200] Inżynieria”, który chcę podzielić na „200”, „Inżynieria”
— scottysseus

3
Och, wow, rozumiem ... Musiałem użyć dwóch odwrotnych ukośników zamiast jednego. String[] strings = codes.get(x).split("\\[|\\]| ");<- kod dla wszystkich zainteresowanych
— scottysseus

13

Za pomocą Guava możesz to zrobić:

Iterable<String> tokens = Splitter.on(CharMatcher.anyOf("-.")).split(pdfName);

4

W przypadku sekwencji dwóch znaków jako delimetrów „AND” i „OR” należy to zrobić. Nie zapomnij przyciąć podczas używania.

 String text ="ISTANBUL AND NEW YORK AND PARIS OR TOKYO AND MOSCOW";
 String[] cities = text.split("AND|OR"); 

Wynik: miasta = {„ISTANBUŁ”, „NOWY JORK”, „PARYŻ”, „TOKIO”, „MOSKWA”}


Jak uzyskać dane wyjściowe takie jak {„ISTANBUŁ I”, „NOWY JORK I”, „PARYŻ LUB”, „TOKIO I”, „MOSKWA”}
— Ahamadullah Saikat

3

Użyłbym Apache Commons:

import org.apache.commons.lang3.StringUtils;

private void getId(String pdfName){
    String[] tokens = StringUtils.split(pdfName, "-.");
}

Dzieli się na jednym z określonych separatorów, w przeciwieństwie do tego, StringUtils.splitByWholeSeparator(str, separator)który używa pełnego łańcucha jako separatora


3
String[] token=s.split("[.-]");

9
Pomóż walczyć z nieporozumieniem, że StackOverflow jest bezpłatną usługą pisania kodu, rozszerzając odpowiedź tylko na kod z pewnymi wyjaśnieniami.
— Yunnosch

2

Lepiej użyć czegoś takiego:

s.split("[\\s\\-\\.\\'\\?\\,\\_\\@]+");

Dodałem kilka innych znaków jako przykład. Jest to najbezpieczniejszy sposób użycia, ponieważ sposób .i sposób 'leczenia.


1

Możesz również podać wyrażenie regularne jako argument w metodzie split () .. patrz poniższy przykład ....

private void getId(String pdfName){
String[]tokens = pdfName.split("-|\\.");
}

1

Wypróbuj ten kod:

var string = 'AA.BB-CC-DD.zip';
array = string.split(/[,.]/);

1
Pomóż walczyć z nieporozumieniem, że StackOverflow jest bezpłatną usługą pisania kodu, rozszerzając odpowiedź tylko na kod z pewnymi wyjaśnieniami.
— Yunnosch

0
s.trim().split("[\\W]+") 

powinno działać.


2
Po pierwsze, nie, to nie działa - może możesz spróbować przed opublikowaniem? Zatem ta odpowiedź jest taka sama jak twoja - ale działa. Na koniec powinieneś sprawdzić formatowanie ( powinno działać ).
— Arount,

1
Pomóż walczyć z nieporozumieniem, że StackOverflow jest bezpłatną usługą pisania kodu, rozszerzając odpowiedź tylko na kod z pewnymi wyjaśnieniami.
— Yunnosch

-1

Jeśli wiesz, że żądło będzie zawsze w tym samym formacie, najpierw podziel ciąg na podstawie .i zapisz ciąg przy pierwszym indeksie w zmiennej. Następnie podziel ciąg w drugim indeksie na podstawie -i przechowuj indeksy 0, 1 i 2. Na koniec podziel indeks 2 z poprzedniej tablicy na podstawie .i powinieneś uzyskać wszystkie odpowiednie pola.

Zapoznaj się z następującym fragmentem kodu:

String[] tmp = pdfName.split(".");
String val1 = tmp[0];
tmp = tmp[1].split("-");
String val2 = tmp[0];
...

6
Można to zrobić w jednym kroku, więc zrób to w jednym kroku. Zobacz pozostałe odpowiedzi.
— Kaj

2
pdfName.split(".")daje tablicę o zerowej długości.
— Alan Moore

1) .Potrzebuje ucieczki jako\\.
— Shri,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.