Regular Expression trong JavaScript

Regular Expression trong JavaScript

Giới thiệu

Trong JavaScript, biểu thức chính quy (Regular Expression hay RegEx) là một đối tượng mô tả một chuỗi các ký tự được sử dụng để xác định một mẫu tìm kiếm. Ví dụ:

/^a...s$/

Đoạn mã trên xác định một mẫu Regular Expression. Nghĩa là: chuỗi năm chữ cái bất kỳ bắt đầu bằng a và kết thúc bằng s.

Một mẫu được xác định bằng Regular Expression có thể được sử dụng để khớp (match) với một chuỗi.

StringMatched?
absNo match
aliasMatch
abyssMatch
AliasNo match
An abacusNo match

Tạo một Regular Expression

Có hai cách để tạo một biểu thức chính quy trong JavaScript:

Sử dụng cụm từ thông dụng

Biểu thức chính quy bao gồm một mẫu nằm giữa dấu gạch chéo /.

cost regularExp = /abc/Code language: JavaScript (javascript)

Trong đó, /abc/ là một biểu thức chính quy.

Sử dụng hàm khởi tạo RegExp()

Bạn cũng có thể tạo một biểu thức chính quy bằng cách gọi hàm khởi tạo RegExp().

const reguarExp = new RegExp('abc)Code language: JavaScript (javascript)

Ví dụ:

const regex = new RegExp(/^a...s$/);
console.log(regex.test('alias')); // trueCode language: JavaScript (javascript)

Trong ví dụ trên, alias khớp với mẫu RegEx /^a...s$/

Ở đây, phương thức test() được sử dụng để kiểm tra xem chuỗi có khớp với mẫu hay không.

Còn một số phương thức khác có sẵn để sử dụng với JavaScript Regular Expression. Để tìm hiểu rõ hơn, hãy xem ở phía cuối bài viết nhé!


Xác định mẫu bằng Regular Expression

Để xác định biểu thức chính quy, siêu ký tự (metacharacter) được sử dụng. Trong ví dụ trên (/^a...s$/), ^$ là các siêu ký tự.


Siêu ký tự là các ký tự được RegEx diễn giải theo một cách đặc biệt. Đây là danh sách các siêu ký tự:

Siêu ký tự

[] . ^ $ * + ? {} () \ |


[] – Dấu ngoặc vuông

Dấu ngoặc vuông xác định một tập hợp các ký tự bạn muốn khớp.

Biểu thức: [abc]

StringMatched?
a1 match
ac2 matches
Hey JudeNo match
abc de ca5 matches

Ở đây, [abc] sẽ khớp nếu chuỗi có chứa bất kỳ ký tự a, b hoặc c.

[a-e] khớp với [abcde].

[1-4] khớp với [1234].

[0-39] khớp với [01239].

Ngoài ra, có thể thêm dấu ^ sau dấu ngoặc vuông mở đầu để đảo ngược tập hợp ký tự.

[^abc] có nghĩa là bất kỳ ký tự nào ngoại trừ a hoặc b hoặc c.

[^0-9] có nghĩa là bất kỳ ký tự nào không phải chữ số.


. – Dấu chấm

Dấu chấm khớp với bất kỳ ký tự đơn nào (ngoại trừ xuống dòng '\n').

Biểu thức: ..

StringMatched?
aNo match
ac1 match
acd1 match
acde2 matches (gồm 4 ký tự)

^ – Dấu mũ

Dấu mũ ^ được sử dụng để kiểm tra xem một chuỗi có bắt đầu bằng một ký tự nhất định hay không.

Biểu thức: ^a

StringMatched?
a1 match
abc1 match
bacNo match

Biểu thức: ^ab

StringMatched?
abc1 match
acbNo match

$ – Dấu dollar

Dấu đô la $ được sử dụng để kiểm tra xem một chuỗi có kết thúc bằng một ký tự nhất định hay không.

Biểu thức: a$

StringMatched?
a1 match
formula1 match
capNo match

* – Dấu sao

Dấu sao * khớp với chuỗi có thành phần trước dấu * xuất hiện >= 0 lần (có thể không xuất hiện).

Biểu thức: ma*n

StringMatched?
mn1 match
man1 match
mann1 match
mainNo match (vì theo sau a không phải n)
woman1 match

+ – Dấu cộng

Dấu cộng + khớp với chuỗi có thành phần trước dấu + xuất hiện >= 1 lần.

Biểu thức: ma+n

StringMatched?
mnNo match (vì không chứa a)
man1 match
mann1 match
mainNo match (vì theo sau a không phải n)
woman1 match

? – Dấu hỏi chấm

Dấu hỏi chấm ? khớp với chuỗi có thành phần trước dấu ? xuất hiện 0 hoặc 1 lần.

Biểu thức: ma?n

StringMatched?
mn1 match
man1 match
mannNo match (có nhiều hơn 1 ký tự n)
mainNo match (vì theo sau a không phải n)
woman1 match

{} – Dấu ngoặc nhọn

Xem xét đoạn mã này: {n, m}. Điều này có nghĩa là có ít nhất n và nhiều nhất m lần lặp lại thành phần đó.

Biểu thức: a{2, 3}

StringMatched?
abc datNo match
abc daat1 match (ở daat)
aabc daaat2 matches (ở aabcdaaat)
aabc daaaat2 matches (ở aabcdaaaat)

Hãy thử một ví dụ nữa. RegEx [0-9]{2,4} này khớp với ít nhất 2 chữ số nhưng không nhiều hơn 4 chữ số.

StringMatched?
ab123csde1 match (ở ab123csde)
12 và 3456733 matches (12, 345673)
1 và 2
No match

| – Dấu sổ thẳng

Xem xét đoạn mã này: n|m. Dấu sổ thẳng | được sử dụng để tìm chuỗi hoặc là n hoặc là m.

Biểu thức: a|b

StringMatched?
cdeNo match
ade1 match (ở ade)
acdbea3 matches (ở acdbea)

() – Dấu ngoặc tròn

Dấu ngoặc tròn () được sử dụng để nhóm các mẫu con. Ví dụ: (a|b|c)xz khớp với bất kỳ chuỗi nào khớp với a hoặc b hoặc c theo sau là xz.

Biểu thức: (a|b|c)xz

StringMatched?
ab xzNo match
abxz1 match (ở abxz)
axz cabxz2 matches (ở axzbc cabxz)

\ – Dấu gạch chéo ngược

Dấu gạch chéo ngược được sử dụng để thể hiện tất cả các ký tự theo sau nó, bao gồm các siêu ký tự (metacharacter).

\$a khớp nếu một chuỗi chứa $ theo sau là a. Ở đây, $ không phải là RegEx.

Nếu bạn không chắc liệu một ký tự có đặc biệt hay không, bạn có thể đặt \ trước nó. Điều này đảm bảo rằng sẽ không bỏ sót trường hợp nào.


Special Sequences

Special Sequences là chuỗi đặc biệt và được bắt đầu bằng ký tự \, nó có ý nghĩa đặc biệt và thường trợ giúp cho việc mô tả Regular Expression được gọn gàng hơn.

\A

Bắt đầu chuỗi bằng ký tự chỉ định.

Biểu thức: \Athe

StringMatched?
the sunMatch
In the sunNo match

\b

Bắt đầu hoặc kết thúc của một từ bằng ký tự chỉ định.

Biểu thức: \bfoo

StringMatched?
footballMatch
a footballMatch

Biểu thức: foo\b

StringMatched?
a footballNo match
the fooMatch
the afoo testMatch
the afootestNo match

\B

Ngược với \b, khớp với các ký tự chỉ định nhưng không nằm ở đầu hoặc cuối từ.

Biểu thức: \Bfoo

StringMatched?
footballNo match
a footballNo match

Biểu thức: foo\B

StringMatched?
a footballMatch
the fooNo match
the afoo testNo match
the afootestMatch

\d

Chuỗi chứa ký tự là chữ số, giống với [0-9].

Biểu thức: \d

StringMatched?
12abc33 matches (ở 12abc3)
JavaScriptNo match

\D

Chuỗi không chứa ký tự là số, giống với [^0-9].

Biểu thức: \D

StringMatched?
1ab34"503 matches (ở 1ab34"50)
1345No match

\s

Chuỗi chứa khoảng trắng, giống với [\t\n\r\f\v].

Biểu thức: \s

StringMatched?
JavaScript RegEx1 match
JavaScriptRegExNo match

\S

Chuỗi không chứa khoảng trắng, giống với [^\t\n\r\f\v].

Biểu thức: \S

StringMatched?
a b2 matches (at a b)
No match

\w

Chuỗi chứa bất kỳ ký tự nào trong nhóm từ a tới Z, từ 0 tới 9 và dấu _ (underscore), giống với [a-zA-Z0-9_].

Biểu thức: \w

StringMatched?
12&": ;c3 matches (ở 12&": ;c)
%"> !No match

\W

Ngược lại với \w.

Biểu thức: \W

StringMatched?
1a2%c1 match (ở 1a2%c)
JavaScriptNo match

\Z

Kết thúc chuỗi bằng các ký tự được chỉ định.

Biểu thức: JavaScript\Z

StringMatched?
I like JavaScript1 match
I like JavaScript ProgrammingNo match
JavaScript is funNo match

Mẹo: Để build và test các biểu thức chính quy, bạn có thể sử dụng các công cụ kiểm tra RegEx như regex101. Công cụ này không chỉ giúp bạn trong việc tạo biểu thức chính quy mà còn giúp bạn tìm hiểu chúng.


Phương thức của Regular Expression trong JavaScript

Như đã đề cập ở trên, bạn có thể sử dụng RegExp() hoặc cụm từ thông dụng để tạo RegEx trong JavaScript.

const regex1 = /^ab/;
const regex2 = new Regexp('/^ab/');

Trong JavaScript, bạn có thể sử dụng các biểu thức chính quy với các phương thức RegExp()test()execute().

Ngoài ra, còn có một số phương thức chuỗi cho phép bạn chuyển RegEx làm tham số của chúng như match(), replace(), search()split().

MethodDescription
exec()Tìm kiếm chuỗi phù hợp với mẫu so khớp, trả về một mảng chứa kết quả tìm kiếm
test()Kiểm tra mẫu có khớp với chuỗi hay không, trả về true hoặc false
match()Tìm kiếm chuỗi phù hợp với mẫu so khớp, trả về một mảng chứa kết quả tìm kiếm hoặc null nếu không tìm thấy
search()Tìm kiếm chuỗi phù hợp với mẫu so khớp, trả về vị trí của chuỗi đó hoặc -1 nếu không tìm thấy
replace()Thay thế chuỗi bằng chuỗi khác phù hợp với mẫu tìm kiếm
split()Ngắt chuỗi thành một mảng các chuỗi con

Ví dụ 1: Biểu thức chính quy

const string = 'Find me';
const pattern = /me/;

// search if the pattern is in string variable
const result1 = string.search(pattern);
console.log(result1); // 5

// replace the character with another character
const string1 = 'Find me';
string1.replace(pattern, 'found you'); // Find found you

// splitting strings into array elements
const regex1 = /[\s,]+/;
const result2 = 'Hello world! '.split(regex1);
console.log(result2); // ["I", "am", "learning", "JavaScript", "RegEx"]

// searching the phone number pattern
const regex2 = /(\d{3})\D(\d{3})-(\d{4})/g;
const result3 = regex2.exec('My phone number is: 555 123-4567.');
console.log(result3); // ["555 123-4567", "555", "123", "4567"]

Regular Expression Flags

Cờ (Flag) được sử dụng với các cụm từ thông dụng cho phép các tùy chọn khác nhau như tìm kiếm toàn cục, tìm kiếm không phân biệt chữ hoa chữ thường, v.v. Chúng có thể được sử dụng riêng biệt hoặc cùng nhau.

FlagsDescription
gso khớp toàn bộ chuỗi cần tìm
mso khớp luôn cả các dữ liệu xuống dòng
iso khớp không quan tâm đến chữ hoa chữ thường

Ví dụ 2: Chính sửa Regular Expression

const string = 'Hello hello hello';

// performing a replacement
const result1 = string.replace(/hello/, 'world');
console.log(result1); // Hello world hello

// performing global replacement
const result2 = string.replace(/hello/g, 'world');
console.log(result2); // Hello world world

// performing case-insensitive replacement
const result3 = string.replace(/hello/i, 'world');
console.log(result3); // world hello hello

// performing global case-insensitive replacement
const result4 = string.replace(/hello/gi, 'world');
console.log(result4); // world world world

Ví dụ 3: Xác thực số điện thoại

// program to validate the phone number

function validatePhone(num) {

    // regex pattern for phone number
    const re = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/g;

    // check if the phone number is valid
    let result = num.match(re);
    if (result) {
        console.log('The number is valid.');
    }
    else {
        let num = prompt('Enter number in XXX-XXX-XXXX format:');
        validatePhone(num);
    }
}

// take input
let number = prompt('Enter a number XXX-XXX-XXXX');

validatePhone(number);

Kết quả:

Enter a number XXX-XXX-XXXX: 2343223432
Enter number in XXX-XXX-XXXX format: 234-322-3432
The number is valid

Ví dụ 4: Xác thực địa chỉ email

// program to validate the email address

function validateEmail(email) {

    // regex pattern for email
    const re = /\S+@\S+\.\S+/g;

    // check if the email is valid
    let result = re.test(email);
    if (result) {
        console.log('The email is valid.');
    }
    else {
        let newEmail = prompt('Enter a valid email:');
        validateEmail(newEmail);
    }
}

// take input
let email = prompt('Enter an email: ');

validateEmail(email);

Kết quả:

Enter an email: hellohello
Enter a valid email: learningJS@gmail.com
The email is valid.Code language: CSS (css)

Kết luận

Regular Expression thật sự rất mạnh mẽ và nó sẽ giúp các bạn xử lý được rất nhiều bài toán khó, phức tạp nếu áp dụng cách thông thường. Nhưng nó cũng thực sự khá rối rắm với nhưng người chưa tìm hiểu kỹ về nó. Hy vọng các bạn sẽ tìm được niềm vui khi sử dụng Regular Expression với JavaScript.

Các bạn có thể tham khảo các bài viết hay về JavaScript tại đây.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Bình luận