Чому String.split потребує розмежувача труби, щоб уникнути?


140

Я намагаюся розібрати файл, у якому кожен рядок із значеннями, розміщеними в трубі. Він не працював правильно, коли я не уникав роздільника труби методом спліт, але він працював правильно після того, як я уникнув трубу, як показано нижче.

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

Може хтось, будь ласка, пояснить, чому для split()методу потрібно уникати характер труби ?


13
Наведені нижче відповіді відповіли на "чому", але просто FYI, якщо ви намагаєтеся відповідати буквальному рядку, ви також можете подивитися на Pattern.quote . Він займає a Stringі повертає регулярний вираз, Stringякий буде відповідати вхідному (тобто він піклується про всі втечі для вас).
yshavit

+1 заPattern.quote
redDevil

Відповіді:


175

String.splitочікує регулярного аргументу вираження. Немальований |аналіз аналізується як регулярне вираження, що означає "порожній рядок або порожній рядок", а це не те, що ви маєте на увазі.


76

Оскільки синтаксис для цього параметра для розбиття є регулярним виразом, де в '|' має особливе значення АБО, а '\ |' означає буквальне '|' тому рядок "\\ |" означає регулярний вираз '\ |' що означає точно відповідати символу '|'.


1
Дякую за це пояснення. Я майже завжди забуваю використовувати подвійну втечу. Тепер, коли я знаю, чому це саме так, це, безумовно, допоможе мені згадати відтепер.
sufinawaz

Що станеться, якщо значення рядка String містить деякі символи Труби? Як би ви могли розколотись, не розщеплюючи трубу, що втекла \ | ?
AlexandreJ

@AlexandreJ Ви питаєте, як розділити рядок, який виглядає так: Some|Delimited|Text|With|An\|Embedded|Pipe|Charна ("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")? Функція розбиття не підтримує схожість, але це можливо, ви зможете створити регулярний вираз, який буде працювати в цьому випадку, як, наприклад, з негативним твердженням нульової ширини, огляньте групу: (?<!\\)\|що було бline.split("(?<!\\\\)\\|");
dlamblin

6

Ви можете просто зробити це:

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

вам потрібно уникнути \ щоб використовувати regex "yourString.split (" \\ | ")" це правильна формула.
mautrok
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.