Perché String.split ha bisogno del escape del delimitatore di pipe?


140

Sto cercando di analizzare un file che ha ogni riga con valori delimitati da pipe. Non ha funzionato correttamente quando non sono uscito dal delimitatore di pipe nel metodo split, ma ha funzionato correttamente dopo essere uscito dal pipe come di seguito.

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;
}

Qualcuno può spiegare perché il carattere pipe deve essere evitato per il split()metodo?


13
Le risposte di seguito hanno risposto al "perché", ma solo FYI, se stai cercando di abbinare una stringa letterale potresti anche guardare Pattern.quote . Prende a Stringe restituisce una regex Stringche corrisponderà all'input (ovvero, si occupa di tutte le fughe per te).
yshavit,

+1 perPattern.quote
redDevil

Risposte:


175

String.splitsi aspetta un argomento di espressione regolare. Un non escape |viene analizzato come regex che significa "stringa vuota o stringa vuota", che non è ciò che intendi.


76

Perché la sintassi per quel parametro da dividere è un'espressione regolare, dove in '|' ha un significato speciale di OR e un '\ |' significa letterale '|' quindi la stringa "\\ |" indica l'espressione regolare '\ |' il che significa che corrisponde esattamente al carattere "|".


1
Grazie per questa spiegazione Quasi sempre dimentico di usare la doppia fuga. Ora che so perché è così, sicuramente mi aiuterà a ricordare d'ora in poi.
sufinawaz,

Cosa succede se il valore della linea String ha alcuni caratteri Pipe? Come saresti in grado di dividere senza dividere il tubo di escape \ | ?
AlexandreJ,

@AlexandreJ Stai chiedendo come dividere una linea simile a: Some|Delimited|Text|With|An\|Embedded|Pipe|Charin ("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")? La funzione split non supporta l'escaping in questo modo, ma potresti essere in grado di creare un'espressione regolare che funzionerà per questo caso, come con un'asserzione negativa a larghezza zero dietro il gruppo: (?<!\\)\|che sarebbeline.split("(?<!\\\\)\\|");
dlamblin

6

Puoi semplicemente farlo:

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

devi scappare da \ per usare sei regex "yourString.split (" \\ | ")" questa è la formula giusta.
Mautrok,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.