Tại sao String.split cần thoát dấu phân cách đường ống?


140

Tôi đang cố gắng phân tích một tệp có mỗi dòng với các giá trị được phân tách bằng đường ống. Nó không hoạt động chính xác khi tôi không thoát khỏi dấu phân cách đường ống trong phương pháp phân tách, nhưng nó hoạt động chính xác sau khi tôi thoát khỏi đường ống như dưới đây.

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

Ai đó có thể vui lòng giải thích tại sao nhân vật ống cần được thoát cho split()phương thức không?


13
Các câu trả lời dưới đây đã trả lời "tại sao", nhưng chỉ là FYI, nếu bạn đang cố gắng khớp với một chuỗi chữ, bạn cũng có thể nhìn vào Pattern.quote . Nó nhận một Stringvà trả về một regex Stringsẽ khớp với đầu vào (nghĩa là, nó sẽ chăm sóc tất cả các lối thoát cho bạn).
yshavit

+1 choPattern.quote
redDevil

Câu trả lời:


175

String.splitmong đợi một đối số biểu thức chính quy. Một |chuỗi không được giải mã được phân tích cú pháp dưới dạng regex có nghĩa là "chuỗi rỗng hoặc chuỗi rỗng", đó không phải là ý của bạn.


76

Bởi vì cú pháp cho tham số đó cần phân tách là một biểu thức chính quy, trong đó '|' có ý nghĩa đặc biệt là OR và '\ |' có nghĩa là một chữ '|' vì vậy chuỗi "\\ |" có nghĩa là biểu thức chính quy '\ |' có nghĩa là khớp chính xác với ký tự '|'.


1
Cảm ơn lời giải thích này. Tôi hầu như luôn quên sử dụng lối thoát kép. Bây giờ tôi biết tại sao nó lại như vậy, nó chắc chắn sẽ giúp tôi nhớ từ bây giờ.
sufinawaz

Điều gì xảy ra nếu giá trị của dòng String có một số ký tự ống? Làm thế nào bạn có thể phân chia mà không tách ống thoát \ | ?
AlexandreJ

@AlexandreJ Bạn có hỏi làm thế nào để tách một dòng trông giống như: Some|Delimited|Text|With|An\|Embedded|Pipe|Charthành ("Some", "Delimited", "Text", "With", "An\|Embedded", "Pipe", "Char")? Hàm phân tách không hỗ trợ thoát như thế này, nhưng bạn có thể tạo một biểu thức chính quy sẽ hoạt động trong trường hợp này, giống như với một xác nhận phủ định có độ rộng bằng không phía sau nhóm: (?<!\\)\|sẽ làline.split("(?<!\\\\)\\|");
dlamblin

6

Bạn chỉ có thể làm điều này:

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

bạn phải thoát \ để sử dụng regex "yourString.split (" \\ | ")" đó là công thức phù hợp.
mautrok
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.