Thuật ngữ được sử dụng trong câu trả lời này:
- Khớp cho biết kết quả của việc chạy mẫu RegEx của bạn đối với chuỗi của bạn như vậy :
someString.match(regexPattern)
.
- Các mẫu trùng khớp cho biết tất cả các phần khớp của chuỗi đầu vào, tất cả nằm trong mảng khớp . Đây là tất cả các phiên bản của mẫu của bạn bên trong chuỗi đầu vào.
- Các nhóm phù hợp chỉ ra tất cả các nhóm cần bắt, được xác định trong mẫu RegEx. (Các mẫu bên trong dấu ngoặc đơn, như vậy :
/format_(.*?)/g
, nơi (.*?)
sẽ là một nhóm phù hợp.) Chúng nằm trong các mẫu phù hợp .
Sự miêu tả
Để có quyền truy cập vào các nhóm phù hợp , trong mỗi mẫu phù hợp , bạn cần một hàm hoặc một cái gì đó tương tự như lặp lại trong trận đấu . Có một số cách bạn có thể làm điều này, như nhiều câu trả lời khác cho thấy. Hầu hết các câu trả lời khác sử dụng vòng lặp while để lặp lại tất cả các mẫu phù hợp , nhưng tôi nghĩ tất cả chúng ta đều biết những nguy cơ tiềm ẩn với cách tiếp cận đó. Nó là cần thiết để phù hợp với một new RegExp()
thay vì chỉ mẫu, mà chỉ được đề cập trong một bình luận. Điều này là do .exec()
phương thức này hoạt động tương tự như hàm tạo - nó dừng mỗi khi có kết quả khớp , nhưng giữ cho nó .lastIndex
tiếp tục từ đó trong .exec()
cuộc gọi tiếp theo .
Mã ví dụ
Dưới đây là một ví dụ về hàm searchString
trả về một Array
trong tất cả các mẫu phù hợp , trong đó mỗi mẫu match
là một Array
với tất cả các nhóm được khớp . Thay vì sử dụng một vòng lặp while, tôi đã cung cấp các ví dụ bằng cách sử dụng cả Array.prototype.map()
chức năng cũng như cách thức hiệu quả hơn - sử dụng đơn giản for
-loop.
Phiên bản súc tích (ít mã hơn, nhiều cú pháp hơn)
Đây là ít hiệu suất hơn vì về cơ bản họ thực hiện một forEach
-loop thay vì for
-loop nhanh hơn .
// Concise ES6/ES2015 syntax
const searchString =
(string, pattern) =>
string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
// Or if you will, with ES5 syntax
function searchString(string, pattern) {
return string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
Phiên bản biểu diễn (nhiều mã hơn, ít cú pháp hơn)
// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
let result = [];
const matches = string.match(new RegExp(pattern.source, pattern.flags));
for (let i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
};
// Same thing, but with ES5 syntax
function searchString(string, pattern) {
var result = [];
var matches = string.match(new RegExp(pattern.source, pattern.flags));
for (var i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
Tôi vẫn chưa so sánh các lựa chọn thay thế này với các câu trả lời trước đây được đề cập trong các câu trả lời khác, nhưng tôi nghi ngờ phương pháp này ít hiệu quả hơn và ít an toàn hơn các phương pháp khác.