JavaRush /Blog Java /Random-VI /Khái niệm cơ bản về biểu thức chính quy trong Java. Phần ...
articles
Mức độ

Khái niệm cơ bản về biểu thức chính quy trong Java. Phần 3

Xuất bản trong nhóm
Hãy tiếp tục nghiên cứu về biểu thức chính quy. Trong bài viết này, chúng ta sẽ xem xét các lớp ký tự được xác định trước cũng như định lượng (tìm kiếm chuỗi). Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 1

Các lớp ký tự được xác định trước

API lớp Patternchứa các lớp ký tự được xác định trước cung cấp các phím tắt thuận tiện cho các biểu thức chính quy thường được sử dụng. Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 2Trong bảng này, các cấu trúc ở cột bên trái là biểu diễn tốc ký của các biểu thức ở cột bên phải. Ví dụ: \dcó nghĩa là một số (0-9), \wcó nghĩa là bất kỳ chữ hoa hoặc chữ thường, dấu gạch dưới hoặc số). Sử dụng các lớp ký tự được xác định trước bất cứ khi nào có thể. Điều này sẽ làm cho mã của bạn dễ đọc hơn và sửa lỗi hơn. Các cấu trúc bắt đầu bằng dấu gạch chéo ngược được gọi là thoát hoặc được bảo vệ. Trong các bài viết trước, chúng ta đã nói về việc thoát các ký tự đặc biệt bằng dấu gạch chéo ngược hoặc ký hiệu \Q\Esử dụng chúng làm ký tự thông thường. Nếu bạn sử dụng dấu gạch chéo ngược với các ký tự thông thường (chữ cái), thì bạn cần thoát khỏi dấu gạch chéo ngược để biểu thức biên dịch.
private final String REGEX = "\\d"; // цифра
Trong ví dụ này \d, một biểu thức chính quy; dấu gạch chéo ngược bổ sung là cần thiết để chương trình biên dịch. Chương trình thử nghiệm của chúng tôi đọc các biểu thức chính quy trực tiếp từ bảng điều khiển, do đó không cần thêm dấu gạch chéo. Ví dụ sau đây minh họa cách sử dụng các lớp ký tự được xác định trước: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 3Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 4Trong ba ví dụ đầu tiên, biểu thức chính quy chỉ đơn giản là " ." (ký tự đặc biệt dấu chấm), có nghĩa là bất kỳ ký tự nào. Vì vậy, việc tìm kiếm đã thành công trong mọi trường hợp. Các ví dụ khác sử dụng các lớp ký tự được xác định trước, ý nghĩa của chúng mà chúng ta đã thảo luận trong bảng trên.

định lượng

Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 4Bộ định lượng cho phép bạn chỉ định số lần xuất hiện của một ký tự trong chuỗi. Chúng ta hãy xem xét kỹ hơn sự phức tạp của cách thức hoạt động của các bộ định lượng tham lam, lười biếng và rất tham lam. Thoạt nhìn có vẻ như các bộ định lượng X?, X?? và X?+ hoạt động theo cách tương tự: “X hiện diện một lần hoặc hoàn toàn không hiện diện”. Có một số khác biệt nhỏ trong việc triển khai các bộ định lượng này mà chúng ta sẽ xem xét bên dưới.

Trận đấu có độ dài bằng 0

Hãy bắt đầu với người tham lam. Hãy viết ba biểu thức chính quy khác nhau: chữ cái “a” với các ký tự đặc biệt ?, * hoặc +. Hãy xem điều gì sẽ xảy ra nếu chúng ta kiểm tra các biểu thức chính quy này trên một dòng trống: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 5Trong ví dụ trên, việc tìm kiếm thành công trong hai trường hợp đầu tiên, vì các biểu thức a? và a* cho phép thiếu ký tự a trong chuỗi. Cũng lưu ý rằng chỉ số trận đấu bắt đầu và trận đấu cuối cùng giống nhau (0). Vì chuỗi đầu vào không có độ dài nên chương trình không tìm thấy gì :) ở vị trí đầu tiên. Trường hợp này được gọi là trận đấu có độ dài bằng 0. Sự trùng khớp như vậy xảy ra trong một số trường hợp: khi dòng đầu vào trống, ở đầu dòng đầu vào, sau ký tự cuối cùng của dòng hoặc giữa các ký tự trong dòng. Rất dễ nhận thấy các trận đấu có độ dài bằng 0: chúng bắt đầu và kết thúc ở cùng một vị trí. Hãy xem xét thêm một số ví dụ về các kết quả khớp có độ dài bằng 0. Hãy cùng khám phá các kết quả có độ dài bằng 0 bằng một vài ví dụ khác. Hãy thay đổi chuỗi đầu vào thành ký tự "a" và quan sát một hiệu ứng thú vị: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 6Cả ba bộ định lượng đều tìm thấy ký tự "a", nhưng hai bộ định lượng đầu tiên, cho phép thiếu ký tự, đã tìm thấy kết quả khớp có độ dài bằng 0 ở vị trí 1 - sau ký tự cuối cùng của chuỗi. Điều này xảy ra vì chương trình coi ký tự “a” là một chuỗi và “chạy” qua nó cho đến khi không còn kết quả trùng khớp nào nữa. Tùy thuộc vào bộ định lượng được sử dụng, chương trình sẽ tìm thấy hoặc không tìm thấy "không có gì" ở cuối chuỗi. Bây giờ hãy thay đổi chuỗi đầu vào thành một chuỗi gồm năm chữ cái "a": Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 7Biểu thức chính quy a? tìm thấy kết quả khớp cho từng chữ cái trong chuỗi riêng biệt. Biểu thức a* tìm thấy hai kết quả khớp: chuỗi ký tự "a"' và một kết quả khớp có độ dài bằng 0 ở vị trí 5. Và cuối cùng, biểu thức chính quy a+ chỉ tìm thấy chuỗi ký tự “a”, mà không tìm thấy “không có gì” :) Điều gì sẽ xảy ra nếu một chuỗi chứa các ký tự khác nhau được đưa vào làm đầu vào? Ví dụ: "ababaaab": Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 8Ký tự "b" ở các vị trí 1, 3 và 8 và chương trình tìm các kết quả khớp có độ dài bằng 0 tại các vị trí này. Biểu thức chính quy a? không chú ý đến “b” mà chỉ tìm kiếm sự có mặt (hoặc vắng mặt) của ký tự “a”. Nếu bộ định lượng cho phép thiếu "a", tất cả các ký tự trong chuỗi không phải "a" sẽ được hiển thị dưới dạng khớp có độ dài bằng 0. Để tìm các chuỗi có độ dài nhất định, chỉ cần xác định độ dài trong dấu ngoặc nhọn: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 9Biểu thức chính quy a{3} tìm kiếm một chuỗi gồm ba ký tự "a". Không tìm thấy gì ở dòng đầu tiên vì không có đủ chữ a trong dòng. Ký tự thứ hai chứa 3 ký tự mà chương trình tìm thấy. Thử nghiệm thứ ba cũng tìm thấy kết quả khớp ở đầu chuỗi. Mọi thứ sau ký tự thứ 3 không thỏa mãn biểu thức chính quy, trong đoạn mã bên dưới cũng vậy và sẽ có một số kết quả khớp: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 10Để chỉ định độ dài chuỗi tối thiểu, hãy sử dụng:
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
Trong ví dụ này, chương trình chỉ tìm thấy một kết quả khớp vì chuỗi đáp ứng yêu cầu về độ dài chuỗi tối thiểu là (3) ký tự "a". Cuối cùng, đặt độ dài chuỗi tối đa: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 11Trong ví dụ này, trận đấu đầu tiên kết thúc ở ký tự thứ sáu. Trận đấu thứ hai chứa các ký tự sau trận đấu thứ sáu, bởi vì chúng đáp ứng yêu cầu về độ dài tối thiểu. Nếu chuỗi ngắn hơn một ký tự thì sẽ không có kết quả trùng khớp thứ hai.

Sử dụng Nhóm và Lớp Ký tự với Bộ định lượng

Cho đến thời điểm này, chúng tôi đã thử nghiệm bộ định lượng trên các chuỗi chứa cùng một ký tự. Bộ định lượng chỉ áp dụng cho một ký tự duy nhất, vì vậy biểu thức chính quy "abc+" sẽ khớp với các chuỗi chứa "ab" và "c" một hoặc nhiều lần. Nó sẽ không có nghĩa là "abc" một hoặc nhiều lần. Nhưng các bộ định lượng có thể được sử dụng cùng với các nhóm và lớp ký tự, chẳng hạn như [abc]+ (a hoặc b hoặc c, một hoặc nhiều lần) hoặc (abc)+ (“abc” một hoặc nhiều lần). Hãy tìm một nhóm ký tự (con chó), ba lần trên một dòng: Khái niệm cơ bản về biểu thức chính quy trong Java.  Phần 3 - 12Trong ví dụ đầu tiên, chương trình tìm thấy kết quả trùng khớp, bởi vì bộ định lượng mở rộng đến một nhóm ký tự. Nếu bạn bỏ dấu ngoặc, bộ định lượng {3} sẽ chỉ áp dụng cho chữ “g”. Bạn cũng có thể sử dụng bộ định lượng với các lớp ký tự: Основы регулярных выражений в Java. Часть 3 - 13Bộ định lượng {3} áp dụng cho lớp ký tự trong ngoặc trong ví dụ đầu tiên và trong ví dụ thứ hai - chỉ cho ký tự “c”.

Sự khác biệt giữa các bộ định lượng tham lam, lười biếng và quá tham lam

Có sự khác biệt nhỏ giữa các định lượng tham lam, miễn cưỡng và sở hữu. Các bộ định lượng tham lam được đặt tên như vậy vì chúng cố gắng tìm kết quả khớp dài nhất có thể: đầu tiên chương trình cố gắng "ăn" toàn bộ chuỗi, nếu không tìm thấy kết quả khớp thì một ký tự sẽ bị loại bỏ và việc tìm kiếm được lặp lại cho đến khi tìm thấy kết quả khớp hoặc không còn nhân vật nào nữa. Mặt khác, những người lười biếng bắt đầu từ đầu dòng, thêm ký tự này đến ký tự khác cho đến khi tìm thấy kết quả phù hợp. Cuối cùng, định lượng ghen tị sẽ quét toàn bộ chuỗi một lần mà không loại bỏ các ký tự như trong tham lam. Để trình diễn, chúng tôi sẽ sử dụng chuỗi xfooxxxxxxfoo. Основы регулярных выражений в Java. Часть 3 - 14Ví dụ đầu tiên sử dụng bộ định lượng .* tham lam để tìm bất kỳ ký tự nào, 0 lần trở lên, theo sau là các ký tự "f" "o" "o". Vì cantifier là tham lam nên kết quả tìm được sẽ chứa toàn bộ chuỗi. Bộ định lượng tham lam sẽ không tìm thấy tất cả các kết quả khớp trong một chuỗi bởi vì ở bước đầu tiên, sau khi quét toàn bộ chuỗi, nó sẽ tìm thấy kết quả trùng khớp và hoàn thành công việc. Ví dụ thứ hai là lười biếng và bắt đầu từ đầu dòng, thêm từng ký tự. Chương trình bắt đầu bằng việc kiểm tra "sự trống rỗng", nhưng vì chuỗi "foo" không ở đầu dòng, việc tìm kiếm tiếp tục với việc thêm ký tự "x", sau đó kết quả khớp đầu tiên sẽ được tìm thấy giữa các chỉ số 0 và 4. Việc tìm kiếm tiếp tục cho đến cuối dòng và kết quả trùng khớp thứ hai sẽ được tìm thấy giữa chỉ số 4 và 13. Ví dụ thứ ba không tìm thấy sự trùng hợp vì bộ định lượng ghen tị. Trong trường hợp này, biểu thức chính quy .*+ "đã ăn" toàn bộ dòng, không để lại gì cho "foo". Sử dụng bộ định lượng ghen tị khi bạn cần loại bỏ bất cứ thứ gì không cần thiết trong một chuỗi, nó sẽ hiệu quả hơn bộ định lượng tham lam tương đương. Đó là tất cả! Liên kết tới nguồn: Khái niệm cơ bản về biểu thức chính quy trong Java. Phần 3
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION