Dlaczego String.split wymaga zmiany znaku separatora potoku?


140

Próbuję przeanalizować plik, który ma każdy wiersz z wartościami rozdzielanymi potokami. Nie działał poprawnie, gdy nie uniknąłem ogranicznika rury w metodzie dzielonej, ale działał poprawnie po ucieczce z rury, jak poniżej.

private ArrayList<String> parseLine(String line) {
    ArrayList<String> list = new ArrayList<String>();
    String[] list_str = line.split("\\|"); // note the escape "\\" here
    System.out.println(list_str.length);
    System.out.println(line);
    for(String s:list_str) {
        list.add(s);
        System.out.print(s+ "|");
    }
    return list;
}

Czy ktoś może wyjaśnić, dlaczego znak potoku musi zostać zmieniony w split()metodzie?


13
Poniższe odpowiedzi odpowiadały „dlaczego”, ale tylko do Twojej wiadomości, jeśli próbujesz dopasować dosłowny ciąg znaków, możesz również spojrzeć na Pattern.quote . Pobiera a Stringi zwraca wyrażenie regularne, Stringktóre będzie pasowało do danych wejściowych (tj. Zajmie się wszystkimi znakami ucieczki).
yshavit

+1 dlaPattern.quote
redDevil

Odpowiedzi:


175

String.splitoczekuje argumentu wyrażenia regularnego. Brak znaku zmiany znaczenia |jest przetwarzany jako wyrażenie regularne oznaczające „pusty ciąg lub pusty ciąg”, co nie jest tym, o co ci chodzi.


76

Ponieważ składnia tego parametru do podziału jest wyrażeniem regularnym, gdzie w znaku „|” ma specjalne znaczenie LUB i '\ |' oznacza dosłowne „|” więc ciąg „\\ |” oznacza wyrażenie regularne „\ |” co oznacza, że ​​dokładnie dopasuj znak „|”.


1
Dzięki za to wyjaśnienie. Prawie zawsze zapominam o skorzystaniu z podwójnej ucieczki. Teraz, kiedy już wiem, dlaczego tak jest, na pewno pomoże mi to pamiętać od teraz.
sufinawaz

Co się stanie, jeśli wartość wiersza String zawiera kilka znaków potoku? W jaki sposób byłbyś w stanie podzielić bez dzielenia uciekającego potoku \ | ?
AlexandreJ

@AlexandreJ Pytasz, jak podzielić linię, która wygląda następująco: Some|Delimited|Text|With|An\|Embedded|Pipe|Charna ("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")? Funkcja split nie obsługuje uciekając w ten sposób, ale może być w stanie spreparować wyrażenie regularne, że będziemy pracować w tym przypadku, podobnie jak przy zerowej szerokości negatywnej twierdzenie spojrzeć za grupy: (?<!\\)\|co byłobyline.split("(?<!\\\\)\\|");
dlamblin

6

Możesz to po prostu zrobić:

String[] arrayString = yourString.split("\\|");

musisz uciec \, aby użyć wyrażenia regularnego "yourString.split (" \\ | ")", to jest właściwa formuła.
mautrok
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.