JavaScript Regular Expressions and RegExp Object

Xin chào các bạn đang học lập trình! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của các biểu thức chính quy (RegEx) trong JavaScript. Đừng lo lắng nếu bạn chưa từng nghe đến RegEx trước đây - chúng ta sẽ bắt đầu từ những điều cơ bản và dần dần nâng cao. Đến cuối bài hướng dẫn này, bạn sẽ có thể sử dụng sức mạnh của RegEx như một chuyên gia!

JavaScript - RegExp

What are Regular Expressions? (Những gì là Biểu thức Chính quy?)

Biểu thức Chính quy, thường được viết tắt là RegEx, là những công cụ mạnh mẽ cho việc khớp và thao tác chuỗi. Hãy nghĩ về chúng như một ngôn ngữ đặc biệt để mô tả các mẫu trong văn bản. Chúng giống như một chiếc dao quân dụng cho việc làm việc với chuỗi - linh hoạt và vô cùng hữu ích!

Hãy bắt đầu với một ví dụ đơn giản:

let pattern = /hello/;
let text = "Hello, world!";
console.log(pattern.test(text));  // Output: false

Trong ví dụ này, /hello/ là mẫu RegEx của chúng ta, và chúng ta đang kiểm tra xem nó có khớp với văn bản "Hello, world!" hay không. Kết quả là false vì RegEx mặc định là nhạy cảm với chữ cái.

RegExp Object (Đối tượng RegExp)

Trong JavaScript, chúng ta có thể tạo các mẫu RegEx sử dụng đối tượng RegExp. Dưới đây là cách làm:

let pattern1 = new RegExp("hello");
let pattern2 = /hello/;

console.log(pattern1.test("hello world"));  // Output: true
console.log(pattern2.test("hello world"));  // Output: true

Cả hai cách tạo một đối tượng RegExp đều tương đương. Notation văn bản (/pattern/) thường được sử dụng phổ biến hơn nhờ vào sự đơn giản của nó.

Modifiers (Chỉ thị)

Chỉ thị cho phép chúng ta thay đổi cách một mẫu RegEx hoạt động. Hãy xem xét một số chỉ thị phổ biến:

Chỉ thị Mô tả
i Khớp không phân biệt chữ cái
g Khớp toàn cục (tìm tất cả các khớp, không chỉ第一款)
m Khớp nhiều dòng

Dưới đây là một ví dụ sử dụng chỉ thị 'i':

let pattern = /hello/i;
let text = "Hello, World!";
console.log(pattern.test(text));  // Output: true

Bây giờ mẫu của chúng ta khớp với "Hello" không phân biệt chữ cái!

Brackets (Dấu ngoặc)

Dấu ngoặc trong RegEx được sử dụng để xác định một bộ hoặc phạm vi các ký tự để khớp:

Dấu ngoặc Mô tả
[abc] Khớp bất kỳ ký tự nào trong ngoặc
[^abc] Khớp bất kỳ ký tự nào không trong ngoặc
[0-9] Khớp bất kỳ chữ số nào từ 0 đến 9
[a-z] Khớp bất kỳ chữ cái thường nào

Hãy xem một ví dụ:

let pattern = /[aeiou]/;
console.log(pattern.test("hello"));  // Output: true
console.log(pattern.test("why"));    // Output: false

Mẫu này khớp với bất kỳ nguyên âm nào. Nó tìm thấy khớp trong "hello" nhưng không trong "why".

Quantifiers (Quantifier)

Quantifier chỉ định số lần xuất hiện của một ký tự, nhóm hoặc lớp ký tự phải có để tìm thấy khớp.

Quantifier Mô tả
* 0 hoặc nhiều lần xuất hiện
+ 1 hoặc nhiều lần xuất hiện
? 0 hoặc 1 lần xuất hiện
{n} Chính xác n lần xuất hiện
{n,} n hoặc nhiều lần xuất hiện
{n,m} Từ n đến m lần xuất hiện

Dưới đây là một ví dụ thú vị:

let pattern = /ba+/;
console.log(pattern.test("b"));      // Output: false
console.log(pattern.test("ba"));     // Output: true
console.log(pattern.test("baaaa"));  // Output: true

Mẫu này khớp với "ba" tiếp theo là bất kỳ số lượng "a" nào. Nó giống như tiếng kêu của con cừu: "baaaa"!

Literal Characters (Ký tự Literal)

Ký tự literal trong RegEx chỉ là chính nó - chúng khớp với chính mình. Ví dụ, /hello/ khớp với chuỗi chính xác "hello".

let pattern = /hello world/;
console.log(pattern.test("hello world"));  // Output: true
console.log(pattern.test("hello earth"));  // Output: false

Metacharacters (Ký tự Đặc Biệt)

Ký tự đặc biệt có ý nghĩa đặc biệt trong RegEx:

Ký tự Đặc Biệt Mô tả
. Khớp bất kỳ ký tự đơn nào
\d Khớp bất kỳ chữ số nào
\D Khớp bất kỳ ký tự không phải chữ số
\w Khớp bất kỳ ký tự từ nào
\W Khớp bất kỳ ký tự không phải từ nào
\s Khớp bất kỳ ký tự khoảng trống nào
\S Khớp bất kỳ ký tự không phải khoảng trống

Hãy sử dụng một số ký tự đặc biệt:

let pattern = /\d{3}-\d{3}-\d{4}/;
console.log(pattern.test("123-456-7890"));  // Output: true
console.log(pattern.test("abc-def-ghij"));  // Output: false

Mẫu này khớp với định dạng số điện thoại điển hình của Mỹ.

RegExp Properties (Thuộc tính RegExp)

Đối tượng RegExp có một số thuộc tính hữu ích:

Thuộc tính Mô tả
global Có phải cờ "g" được đặt hay không
ignoreCase Có phải cờ "i" được đặt hay không
multiline Có phải cờ "m" được đặt hay không
source Văn bản của mẫu
lastIndex Index để bắt đầu khớp tiếp theo

Dưới đây là cách sử dụng các thuộc tính này:

let pattern = /hello/gi;
console.log(pattern.global);      // Output: true
console.log(pattern.ignoreCase);  // Output: true
console.log(pattern.source);      // Output: "hello"

RegExp Methods (Phương thức RegExp)

Cuối cùng, hãy xem xét một số phương thức chúng ta có thể sử dụng với đối tượng RegExp:

Phương thức Mô tả
exec() Thực hiện tìm kiếm khớp trong một chuỗi
test() Kiểm tra xem có khớp trong chuỗi hay không
toString() Trả về một biểu diễn chuỗi của regexp

Dưới đây là một ví dụ sử dụng exec():

let pattern = /\d+/g;
let text = "I have 2 apples and 3 oranges.";
let match;

while ((match = pattern.exec(text)) !== null) {
console.log(`Found ${match[0]} at index ${match.index}`);
}

// Output:
// Found 2 at index 7
// Found 3 at index 23

Mã này tìm thấy tất cả các số trong văn bản và báo cáo vị trí của chúng.

Và thế là xong! Chúng ta đã bao gồm các основ của Biểu thức Chính quy trong JavaScript. Nhớ rằng, thực hành làm cho hoàn hảo. Hãy thử tạo các mẫu của riêng bạn và kiểm tra chúng. Trước khi bạn biết điều đó, bạn sẽ sử dụng RegEx để giải quyết tất cả các loại vấn đề thao tác chuỗi một cách dễ dàng!

Chúc các bạn may mắn và các biểu thức chính quy của bạn luôn tìm thấy khớp!

Credits: Image by storyset