Groups and backreferences
Nhóm gom nhiều mẫu lại như một tổng thể, và nhóm bắt giữ cung cấp thêm thông tin về kết quả con khi sử dụng mẫu biểu thức chính quy để khớp với một chuỗi. Backreference tham chiếu đến một nhóm đã bắt giữ trước đó trong cùng một biểu thức chính quy.
Try it
// Groups
const imageDescription = "This image has a resolution of 1440×900 pixels.";
const regexpSize = /(\d+)×(\d+)/;
const match = imageDescription.match(regexpSize);
console.log(`Width: ${match[1]} / Height: ${match[2]}.`);
// Expected output: "Width: 1440 / Height: 900."
// Backreferences
const findDuplicates = "foo foo bar";
const regex = /\b(\w+)\s+\1\b/g;
console.log(findDuplicates.match(regex));
// Expected output: Array ["foo foo"]
Các loại
| Ký tự | Ý nghĩa |
|---|---|
(x) |
Nhóm bắt giữ:
Khớp với
Một biểu thức chính quy có thể có nhiều nhóm bắt giữ. Trong kết quả,
các kết quả khớp với nhóm bắt giữ thường nằm trong một mảng có các thành phần theo
cùng thứ tự như dấu ngoặc đơn trái trong nhóm bắt giữ. Đây thường
chỉ là thứ tự của các nhóm bắt giữ. Điều này trở nên quan trọng khi các nhóm bắt giữ
được lồng nhau. Các kết quả khớp được truy cập bằng chỉ mục của các phần tử trong kết quả ( Nhóm bắt giữ có một hình phạt về hiệu suất. Nếu bạn không cần chuỗi con được khớp để được ghi nhớ, hãy ưu tiên dấu ngoặc đơn không bắt giữ (xem bên dưới).
|
(?<Name>x) |
Nhóm bắt giữ có tên:
Khớp với "x" và lưu trữ nó vào
thuộc tính groups của kết quả khớp được trả về dưới tên được chỉ định
bởi
Ví dụ, để trích xuất mã vùng Hoa Kỳ từ một số điện thoại,
chúng ta có thể dùng |
(?:x) |
Nhóm không bắt giữ:
Khớp với "x" nhưng không ghi nhớ
kết quả khớp. Chuỗi con được khớp không thể được truy xuất từ các phần tử của mảng kết quả ( |
(?flags:x), (?flags-flags:x) |
Modifier:
Bật hoặc tắt các cờ được chỉ định chỉ cho mẫu được bao gồm. Chỉ các cờ |
\n
|
Backreference:
Trong đó "n" là một số nguyên dương. Khớp với cùng chuỗi con được khớp bởi
nhóm bắt giữ thứ n trong biểu thức chính quy
(đếm dấu ngoặc đơn trái). Ví dụ,
|
\k<Name> |
Backreference có tên:
Một tham chiếu ngược đến chuỗi con cuối cùng khớp với
nhóm bắt giữ có tên được chỉ định bởi
Ví dụ,
Lưu ý: |
Ví dụ
>Sử dụng nhóm
Trong ví dụ này, chúng ta khớp hai từ ở định dạng có cấu trúc bằng cách sử dụng nhóm bắt giữ để ghi nhớ chúng. \w+ khớp với một hoặc nhiều ký tự từ, và dấu ngoặc đơn () tạo ra một nhóm bắt giữ. Cờ g được dùng để khớp tất cả các lần xuất hiện.
const personList = `First_Name: John, Last_Name: Doe
First_Name: Jane, Last_Name: Smith`;
const regexpNames = /First_Name: (\w+), Last_Name: (\w+)/g;
for (const match of personList.matchAll(regexpNames)) {
console.log(`Hello ${match[1]} ${match[2]}`);
}
Xem thêm ví dụ trong tài liệu tham khảo nhóm bắt giữ.
Sử dụng nhóm có tên
Ví dụ này giống như ví dụ trên, nhưng chúng ta sử dụng nhóm bắt giữ có tên để ghi nhớ các từ được khớp. Bằng cách này, chúng ta có thể truy cập các từ được khớp theo ý nghĩa của chúng.
const personList = `First_Name: John, Last_Name: Doe
First_Name: Jane, Last_Name: Smith`;
const regexpNames =
/First_Name: (?<firstName>\w+), Last_Name: (?<lastName>\w+)/g;
for (const match of personList.matchAll(regexpNames)) {
console.log(`Hello ${match.groups.firstName} ${match.groups.lastName}`);
}
Xem thêm ví dụ trong tài liệu tham khảo nhóm bắt giữ có tên.
Sử dụng nhóm và tham chiếu ngược
Trong ví dụ này, đầu tiên chúng ta khớp một ký tự dấu nháy đơn hoặc dấu nháy kép với ['"], ghi nhớ nó, khớp một số ký tự tùy ý với .*? (*? là một quantifier non-greedy), cho đến khi chúng ta khớp lại ký tự dấu nháy đã ghi nhớ với \1. \1 là một backreference đến nhóm bắt giữ đầu tiên, khớp với cùng loại dấu nháy. Kết quả do đó sẽ là hai chuỗi: "'" và '"'.
const quote = `Single quote "'" and double quote '"'`;
const regexpQuotes = /(['"]).*?\1/g;
for (const match of quote.matchAll(regexpQuotes)) {
console.log(match[0]);
}
Xem thêm ví dụ trong tài liệu tham khảo backreference.
Sử dụng nhóm và chỉ mục kết quả khớp
Bằng cách cung cấp cờ d, các chỉ mục của từng nhóm bắt giữ sẽ được trả về. Điều này đặc biệt hữu ích nếu bạn đang liên kết từng nhóm được khớp với văn bản gốc — ví dụ, để cung cấp chẩn đoán trình biên dịch.
const code = `function add(x, y) {
return x + y;
}`;
const functionRegexp =
/(function\s+)(?<name>[$_\p{ID_Start}][$\p{ID_Continue}]*)/du;
const match = functionRegexp.exec(code);
const lines = code.split("\n");
lines.splice(
1,
0,
" ".repeat(match.indices[1][1] - match.indices[1][0]) +
"^".repeat(match.indices.groups.name[1] - match.indices.groups.name[0]),
);
console.log(lines.join("\n"));
// function add(x, y) {
// ^^^
// return x + y;
// }
Xem thêm
- Hướng dẫn Biểu thức chính quy
- Hướng dẫn Lớp ký tự
- Hướng dẫn Assertions
- Hướng dẫn Quantifiers
RegExp- Tài liệu tham khảo Biểu thức chính quy
- Backreference:
\1,\2 - Nhóm bắt giữ:
(...) - Backreference có tên:
\k<name> - Nhóm bắt giữ có tên:
(?<name>...) - Nhóm không bắt giữ:
(?:...)