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.