Điều này không liên quan gì đến cờ MULTILINE; những gì bạn đang thấy là sự khác biệt giữa find()
và matches()
phương pháp. find()
thành công nếu một trận đấu có thể được tìm thấy ở bất cứ đâu trong chuỗi mục tiêu , trong khi matches()
hy vọng regex khớp với toàn bộ chuỗi .
Pattern p = Pattern.compile("xyz");
Matcher m = p.matcher("123xyzabc");
System.out.println(m.find()); // true
System.out.println(m.matches()); // false
Matcher m = p.matcher("xyz");
System.out.println(m.matches()); // true
Hơn nữa, MULTILINE
không có nghĩa là những gì bạn nghĩ nó làm. Nhiều người dường như nhảy đến kết luận rằng bạn phải sử dụng cờ đó nếu chuỗi mục tiêu của bạn chứa dòng mới - nghĩa là, nếu nó chứa nhiều dòng logic. Tôi đã thấy một số câu trả lời ở đây về SO cho hiệu ứng đó, nhưng trên thực tế, tất cả những gì cờ đó làm là thay đổi hành vi của các neo, ^
và $
.
Thông thường ^
khớp với phần đầu của chuỗi mục tiêu và $
khớp với phần cuối (hoặc trước một dòng mới ở cuối, nhưng chúng ta sẽ bỏ qua phần đó ngay bây giờ). Nhưng nếu chuỗi chứa dòng mới, bạn có thể chọn ^
và $
khớp ở đầu và cuối của bất kỳ dòng logic nào, không chỉ đầu và cuối của toàn bộ chuỗi, bằng cách đặt cờ MULTILINE.
Vì vậy, hãy quên đi những gì MULTILINE
có nghĩa và chỉ cần nhớ những gì nó làm : thay đổi hành vi của ^
và $
neo. DOTALL
Chế độ ban đầu được gọi là "một dòng" (và vẫn còn trong một số hương vị, bao gồm Perl và .NET), và nó luôn gây ra sự nhầm lẫn tương tự. Chúng tôi may mắn rằng các nhà phát triển Java đã sử dụng tên mô tả nhiều hơn trong trường hợp đó, nhưng không có sự thay thế hợp lý nào cho chế độ "đa dòng".
Ở Perl, nơi tất cả sự điên rồ này bắt đầu, họ đã thừa nhận sai lầm của mình và thoát khỏi cả hai chế độ "đa dòng" và "một dòng" trong chế độ Perl 6. Trong hai mươi năm nữa, có lẽ phần còn lại của thế giới sẽ theo sau.