2010-10-06 37 views
9

String để được chiatách một chuỗi có thoát khỏi chuỗi sử dụng biểu thức chính quy trong Java

abc:def:ghi\:klm:nop 

Chuỗi nên được tách ra dựa trên ":" "\" là thoát khỏi nhân vật. Vì vậy, "\:" không nên được coi là mã thông báo.

split (":") mang đến cho

[abc] 
[def] 
[ghi\] 
[klm] 
[nop] 

sản lượng bắt buộc là mảng của chuỗi

[abc] 
[def] 
[ghi\:klm] 
[nop] 

Làm thế nào có thể các \: bị bỏ qua

+0

Có thể làm như sau: 'abc:' def: ghi ": jkl'? –

Trả lời

16

Sử dụng một look-behind assertion:

split("(?<!\\\\):") 

Điều này sẽ chỉ khớp nếu không có \ trước. Sử dụng thoát kép là \\\\ là bắt buộc vì một yêu cầu cho khai báo chuỗi và một cho cụm từ thông dụng.

Lưu ý rằng điều này sẽ không cho phép bạn thoát khỏi dấu gạch chéo ngược, trong trường hợp bạn muốn cho phép mã thông báo kết thúc bằng dấu gạch chéo ngược. Để làm điều đó bạn sẽ phải đầu tiên thay thế tất cả những dấu xồ nguợc đôi với

string.replaceAll("\\\\\\\\", ESCAPE_BACKSLASH) 

(nơi ESCAPE_BACKSLASH là một chuỗi đó sẽ không xảy ra trong đầu vào của bạn) và sau đó, sau khi chia tay bằng cách sử dụng nhìn đằng sau khẳng định, thay thế các chuỗi ESCAPE_BACKSLASH với một dấu chéo ngược unescaped với

token.replaceAll(ESCAPE_BACKSLASH, "\\\\") 
0

Gumbo đã sang phải bằng một look-behind assertion, nhưng trong trường hợp của bạn có chứa chuỗi ký tự thoát thoát (ví dụ \\) ngay trước mặt một dấu phẩy, sự chia rẽ có thể phá vỡ. Xem ví dụ sau:

test1\,test1,test2\\,test3\\\,test3\\\\,test4

Nếu bạn làm một đơn giản nhìn đằng sau chia cho (?<!\\), như Gumbo đề nghị, chuỗi được chia thành hai phần chỉ test1\,test1test2\\,test3\\\,test3\\\\,test4. Điều này là do cái nhìn phía sau chỉ kiểm tra một nhân vật trở lại cho nhân vật thoát. Điều gì thực sự là chính xác, nếu chuỗi được phân tách trên dấu phẩy và dấu phẩy trước một số ký tự thoát.

Để đạt được điều này một chút phức tạp (double) hơn trông-đằng sau biểu hiện là cần thiết:

(?<!(?<![^\\]\\(?:\\{2}){0,10})\\),

Sử dụng biểu thức chính quy phức tạp hơn này trong Java, một lần nữa yêu cầu để thoát khỏi tất cả \ bởi \\. Vì vậy, đây phải là một câu trả lời phức tạp hơn cho câu hỏi của bạn:

"any comma separated string".split("(?<!(?<![^\\\\]\\\\(?:\\\\{2}){0,10})\\\\),"); 

Lưu ý: Java không hỗ trợ lặp lại vô hạn bên trong lookbehinds. Do đó, chỉ có tối đa 10 ký tự thoát kép lặp lại được kiểm tra bằng cách sử dụng biểu thức {0,10}. Nếu cần, bạn có thể tăng giá trị này bằng cách điều chỉnh số sau.

Các vấn đề liên quan