Pourquoi String.split a-t-il besoin d'un séparateur de tube pour être échappé?

140

J'essaie d'analyser un fichier qui a chaque ligne avec des valeurs délimitées par des tuyaux. Cela ne fonctionnait pas correctement lorsque je n'échappais pas au délimiteur de tuyau dans la méthode fractionnée, mais cela fonctionnait correctement après avoir échappé au tuyau comme ci-dessous.

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

Quelqu'un peut-il expliquer pourquoi le caractère pipe doit être échappé pour la split()méthode?

démarrer
la source
13
Les réponses ci-dessous ont répondu au "pourquoi", mais juste pour info, si vous essayez de faire correspondre une chaîne littérale, vous pouvez également consulter Pattern.quote . Il prend a Stringet retourne une expression régulière Stringqui correspondra à l'entrée (c'est-à-dire qu'il s'occupe de tous les échappements pour vous).
yshavit
+1 pourPattern.quote
redDevil

Réponses:

175

String.splitattend un argument d'expression régulière. Un non échappé |est analysé comme une expression régulière signifiant «chaîne vide ou chaîne vide», ce qui n'est pas ce que vous entendez.

Louis Wasserman
la source
76

Parce que la syntaxe de ce paramètre à fractionner est une expression régulière, où dans le '|' a une signification spéciale de OR, et un '\ |' signifie un littéral '|' donc la chaîne "\\ |" signifie l'expression régulière '\ |' ce qui signifie correspondre exactement au caractère «|».

dlamblin
la source
1
Merci pour cette explication. J'oublie presque toujours d'utiliser la double évasion. Maintenant que je sais pourquoi c'est comme ça, ça m'aidera sûrement à me souvenir à partir de maintenant.
sufinawaz
Que se passe-t-il si la valeur de la ligne String contient des caractères Pipe? Comment pourriez-vous diviser sans diviser le tuyau échappé \ | ?
AlexandreJ
@AlexandreJ Demandez-vous comment diviser une ligne qui ressemble à: Some|Delimited|Text|With|An\|Embedded|Pipe|Charen ("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")? La fonction split ne prend pas en charge les échappements comme celui-ci, mais vous pourrez peut-être créer une expression régulière qui fonctionnera dans ce cas, comme avec un regard d'assertion négative de largeur nulle derrière le groupe: (?<!\\)\|ce qui seraitline.split("(?<!\\\\)\\|");
dlamblin
6

Vous pouvez simplement faire ceci:

String[] arrayString = yourString.split("\\|");
Ravinath
la source
vous devez échapper au \ pour utiliser votre regex "yourString.split (" \\ | ")" c'est la bonne formule.
mautrok