2010-11-11 38 views
35

Tôi có một vấn đề với các replaceAll cho một chuỗi multiline:Java regex replaceAll multiline

String regex = "\\s*/\\*.*\\*/"; 
String testWorks = " /** this should be replaced **/ just text"; 
String testIllegal = " /** this should be replaced \n **/ just text"; 

testWorks.replaceAll(regex, "x"); 
testIllegal.replaceAll(regex, "x"); 

Các công trình trên cho testWorks, nhưng không phải cho testIllegal !? Tại sao điều đó và làm thế nào tôi có thể khắc phục điều này? Tôi cần phải thay thế một cái gì đó như một bình luận/* ... */kéo dài nhiều dòng.

+0

Và chuỗi này là gì: '" String s = \ "/ * \";/* chú thích */"' –

+0

Vấn đề là regex toán chỉ nên khớp trong phần đầu của chuỗi. Bây giờ nó trông như thế này: (? S)^\\ s */\\ *. * \\ */Không chắc chắn mặc dù, nếu để làm cho nó miễn cưỡng (? S)^\\ s */\\ *. *? \ */ – Robert

Trả lời

59

Bạn cần phải sử dụng Pattern.DOTALL cờ để nói rằng các dấu chấm phải phù hợp với dòng mới. ví dụ.

Pattern.compile(regex, Pattern.DOTALL).matcher(testIllegal).replaceAll("x") 

hoặc chỉ định cờ trong mẫu sử dụng (?s) ví dụ:

String regex = "(?s)\\s*/\\*.*\\*/"; 
+1

Đây là giải pháp tốt nhất vì nó không tương tác với chính chuỗi regex, bạn chỉ cần chỉ định một cờ. Tôi không biết điều đó, Cảm ơn! – Robert

+1

Nếu bạn có nhiều nhận xét "nhiều dòng", phương pháp này cũng sẽ xóa văn bản giữa các nhận xét đó. Sử dụng phương pháp do Boris đăng. – lepe

7

Ký tự meta . khớp với bất kỳ ký tự nào ngoài dòng mới. Đó là lý do tại sao regex của bạn không hoạt động đối với trường hợp nhiều dòng.

Để sửa lỗi này thay thế . bằng [\d\D] khớp với bất kỳ ký tự nào bao gồm dòng mới.

Code In Action

+1

Hoán đổi trong '[\ d \ D]' cho '.' (thường có nghĩa là' [^ \ n] ', ít nhất trong chế độ' Pattern.UNIX_LINES') đánh tôi là không phù hợp vì nó không rõ ràng những gì nó đang làm, bởi vì nó là 6 ký tự cho 1, và bởi vì có những cách khác để làm điều này. – tchrist

8

Thêm Pattern.DOTALL vào biên dịch hoặc (?s) vào mẫu.