Chrome 73 giới thiệu phương thức String.prototype.matchAll()
. Phương thức này hoạt động tương tự như match()
, nhưng trả về một trình lặp với tất cả các kết quả khớp với biểu thức chính quy trong một biểu thức chính quy toàn cục hoặc cố định. Đây là một cách đơn giản để lặp lại các kết quả trùng khớp, đặc biệt là khi bạn cần quyền truy cập vào các nhóm thu thập.
match() có vấn đề gì?
Câu trả lời ngắn gọn là không có gì, trừ phi bạn đang cố gắng trả về các kết quả trùng khớp toàn cục bằng các nhóm thu thập. Sau đây là một câu đố lập trình dành cho bạn. Hãy xem xét mã sau:
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']
Chạy mã này trong bảng điều khiển và lưu ý rằng mã này trả về một mảng chứa các chuỗi 'test1'
và 'test2'
. Nếu xoá cờ g khỏi biểu thức chính quy, tôi sẽ nhận được tất cả các nhóm thu giữ, nhưng chỉ nhận được kết quả khớp đầu tiên. Thông báo sẽ có dạng như sau:
['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]
Chuỗi này chứa một kết quả trùng khớp thứ hai có thể bắt đầu bằng 'test2'
nhưng tôi không có kết quả trùng khớp đó. Giờ đây, đây là câu đố: làm cách nào để lấy tất cả các nhóm thu thập cho mỗi lần so khớp? Nội dung giải thích về đề xuất String.prototype.matchAll() cho thấy hai phương pháp có thể áp dụng. Tôi sẽ không mô tả các lớp này vì hy vọng bạn sẽ không cần đến chúng nữa.
String.prototype.matchAll()
Ví dụ về nội dung giải thích bằng matchAll()
sẽ như thế nào? Hãy xem qua.
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
console.log(match);
}
Có một vài điều cần lưu ý về vấn đề này. Không giống như match()
trả về một
mảng trên một lượt tìm kiếm toàn cục, matchAll()
trả về một trình lặp hoạt động
một cách hiệu quả với các vòng lặp for...of
. Bộ lặp tạo một mảng cho mỗi lần khớp, bao gồm cả các nhóm thu thập dữ liệu với một số dữ liệu bổ sung. Nếu bạn in các giá trị này vào bảng điều khiển, chúng sẽ có dạng như sau:
['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]
Bạn có thể nhận thấy rằng giá trị cho mỗi kết quả trùng khớp là một mảng có định dạng giống hệt với định dạng do match()
trả về cho các biểu thức chính quy không phải toàn cục.
Nội dung bổ sung
Bài viết này chủ yếu dành cho những người mới làm quen với biểu thức chính quy hoặc không phải là chuyên gia về biểu thức chính quy. Bạn có thể nhận thấy kết quả của cả match() và matchAll() (cho mỗi lần lặp) đều là các mảng có một số thuộc tính được đặt tên bổ sung. Trong khi chuẩn bị bài viết này, tôi nhận thấy các thuộc tính này có một số thiếu sót về tài liệu trên MDN (mà tôi đã khắc phục). Sau đây là nội dung mô tả nhanh.
index
- Chỉ mục của kết quả đầu tiên trong chuỗi ban đầu. Trong ví dụ trên,
test2
bắt đầu ở vị trí 5, do đóindex
có giá trị 5. input
- Chuỗi hoàn chỉnh mà
matchAll()
đã chạy. Trong ví dụ của tôi, đó là'test1test2'
. groups
- Chứa kết quả của mọi nhóm thu thập tên được chỉ định trong biểu thức chính quy.
Kết luận
Nếu tôi có bỏ sót điều gì, vui lòng cho tôi biết trong phần bình luận bên dưới. Bạn có thể đọc thêm về những thay đổi gần đây đối với JavaScript trong các bản cập nhật trước hoặc trên trang web V8.