Assertions
Assertions bao gồm các ranh giới, chỉ ra điểm bắt đầu và kết thúc của dòng và từ, cũng như các mẫu khác cho thấy một phép khớp có thể xảy ra (bao gồm look-ahead, look-behind, và biểu thức điều kiện).
Try it
const text = "A quick fox";
const regexpLastWord = /\w+$/;
console.log(text.match(regexpLastWord));
// Expected output: Array ["fox"]
const regexpWords = /\b\w+\b/g;
console.log(text.match(regexpWords));
// Expected output: Array ["A", "quick", "fox"]
const regexpFoxQuality = /\w+(?= fox)/;
console.log(text.match(regexpFoxQuality));
// Expected output: Array ["quick"]
Các loại
>Assertions kiểu ranh giới
| Ký tự | Ý nghĩa |
|---|---|
^ |
Assertion bắt đầu ranh giới đầu vào:
Khớp với đầu của đầu vào. Nếu cờ Lưu ý: Ký tự này có ý nghĩa khác khi nó xuất hiện ở đầu một character class. |
$ |
Assertion kết thúc ranh giới đầu vào:
Khớp với cuối đầu vào. Nếu cờ |
\b |
Assertion ranh giới từ: Khớp với ranh giới từ. Đây là vị trí mà một ký tự từ không được theo sau hoặc đứng trước bởi một ký tự từ khác, chẳng hạn giữa một chữ cái và khoảng trắng. Lưu ý rằng ranh giới từ được khớp không được bao gồm trong kết quả khớp. Nói cách khác, độ dài của ranh giới từ được khớp là không. Ví dụ:
Để khớp với ký tự backspace ( |
\B |
Assertion không phải ranh giới từ:
Khớp với vị trí không phải ranh giới từ. Đây là vị trí mà ký tự trước và
tiếp theo thuộc cùng loại: cả hai phải là từ, hoặc
cả hai phải không phải từ, ví dụ giữa hai chữ cái hoặc giữa hai
khoảng trắng. Đầu và cuối chuỗi được coi là không phải từ.
Tương tự ranh giới từ được khớp, ranh giới không phải từ được khớp cũng
không được bao gồm trong kết quả khớp. Ví dụ,
|
Các assertions khác
Note:
Ký tự ? cũng có thể được dùng như một quantifier.
| Ký tự | Ý nghĩa |
|---|---|
x(?=y) |
Lookahead assertion:
Khớp với "x" chỉ khi "x" được
theo sau bởi "y". Ví dụ, |
x(?!y) |
Negative lookahead assertion:
Khớp với "x" chỉ khi "x"
không được theo sau bởi "y". Ví dụ, |
(?<=y)x |
Lookbehind assertion:
Khớp với "x" chỉ khi "x" được
đứng trước bởi "y". Ví dụ,
|
(?<!y)x |
Negative lookbehind assertion:
Khớp với "x" chỉ khi
"x" không được đứng trước bởi "y". Ví dụ,
|
Ví dụ
>Ví dụ tổng quan về assertions kiểu ranh giới
// Using Regex boundaries to fix buggy string.
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;
// 1) Use ^ to fix the matching at the beginning of the string, and right after newline.
buggyMultiline = buggyMultiline.replace(/^t/gim, "h");
console.log(1, buggyMultiline); // fix 'tey' => 'hey' and 'tangs' => 'hangs' but do not touch 'traa'.
// 2) Use $ to fix matching at the end of the text.
buggyMultiline = buggyMultiline.replace(/aa$/gim, "ee.");
console.log(2, buggyMultiline); // fix 'traa' => 'tree.'.
// 3) Use \b to match characters right on border between a word and a space.
buggyMultiline = buggyMultiline.replace(/\bi/gim, "t");
console.log(3, buggyMultiline); // fix 'ihe' => 'the' but do not touch 'light'.
// 4) Use \B to match characters inside borders of an entity.
fixedMultiline = buggyMultiline.replace(/\Bo/gim, "e");
console.log(4, fixedMultiline); // fix 'greon' => 'green' but do not touch 'on'.
Khớp đầu đầu vào bằng ký tự điều khiển ^
Dùng ^ để khớp ở đầu đầu vào. Trong ví dụ này, ta có thể lấy các loại trái cây bắt đầu bằng 'A' bằng regex /^A/. Để chọn trái cây phù hợp, ta có thể dùng phương thức filter với hàm arrow.
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Select fruits started with 'A' by /^A/ Regex.
// Here '^' control symbol used only in one role: Matching beginning of an input.
const fruitsStartsWithA = fruits.filter((fruit) => /^A/.test(fruit));
console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
Trong ví dụ thứ hai, ^ được dùng cho cả hai mục đích: khớp ở đầu đầu vào và tạo một character class phủ định hoặc bổ sung khi được dùng trong character classes.
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Selecting fruits that do not start by 'A' with a /^[^A]/ regex.
// In this example, two meanings of '^' control symbol are represented:
// 1) Matching beginning of the input
// 2) A negated or complemented character class: [^A]
// That is, it matches anything that is not enclosed in the square brackets.
const fruitsStartsWithNotA = fruits.filter((fruit) => /^[^A]/.test(fruit));
console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
Xem thêm ví dụ trong tài liệu tham khảo input boundary assertion.
Khớp ranh giới từ
Trong ví dụ này, ta khớp tên trái cây chứa một từ kết thúc bằng "en" hoặc "ed".
const fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
// Select descriptions that contains 'en' or 'ed' words endings:
const enEdSelection = fruitsWithDescription.filter((description) =>
/(?:en|ed)\b/.test(description),
);
console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
Xem thêm ví dụ trong tài liệu tham khảo word boundary assertion.
Lookahead assertion
Trong ví dụ này, ta khớp từ "First" chỉ khi nó được theo sau bởi từ "test", nhưng ta không bao gồm "test" trong kết quả khớp.
const regex = /First(?= test)/g;
console.log("First test".match(regex)); // [ 'First' ]
console.log("First peach".match(regex)); // null
console.log("This is a First test in a year.".match(regex)); // [ 'First' ]
console.log("This is a First peach in a month.".match(regex)); // null
Xem thêm ví dụ trong tài liệu tham khảo lookahead assertion.
Negative lookahead assertion cơ bản
Ví dụ, /\d+(?!\.)/ khớp với một số chỉ khi nó không được theo sau bởi dấu thập phân. /\d+(?!\.)/.exec('3.141') khớp với "141" nhưng không phải "3.
console.log(/\d+(?!\.)/g.exec("3.141")); // [ '141', index: 2, input: '3.141' ]
Xem thêm ví dụ trong tài liệu tham khảo lookahead assertion.
Ý nghĩa khác nhau của tổ hợp '?!' trong assertions và character classes
Tổ hợp ?! có ý nghĩa khác nhau trong assertions như /x(?!y)/ và character classes như [^?!].
const orangeNotLemon =
"Do you want to have an orange? Yes, I do not want to have a lemon!";
// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and Ranges /[^?!]/
const selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
const selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
Lookbehind assertion
Trong ví dụ này, ta thay thế từ "orange" bằng "apple" chỉ khi nó được đứng trước bởi từ "ripe".
const oranges = ["ripe orange A", "green orange B", "ripe orange C"];
const newFruits = oranges.map((fruit) =>
fruit.replace(/(?<=ripe )orange/, "apple"),
);
console.log(newFruits); // ['ripe apple A', 'green orange B', 'ripe apple C']
Xem thêm ví dụ trong tài liệu tham khảo lookbehind assertion.
Xem thêm
- Hướng dẫn Regular expressions
- Hướng dẫn Character classes
- Hướng dẫn Quantifiers
- Hướng dẫn Groups and backreferences
RegExp- Tài liệu tham khảo Regular expressions
- Input boundary assertion:
^,$ - Lookahead assertion:
(?=...),(?!...) - Lookbehind assertion:
(?<=...),(?<!...) - Word boundary assertion:
\b,\B