Чому 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.