Tóm Tắt
I. Giới thiệu
Biểu thức chính quy (regular expressions ) là các mẫu dùng để tìm kiếm các bộ kí tự được kết hợp với nhau trong các chuỗi kí tự. Trong JavaScript thì biểu thức chính quy cũng đồng thời là các đối tượng, tức là khi bạn tạo ra một biểu thức chính quy là bạn có một đối tượng tương ứng. Các mẫu này được sử dụng khá nhiều trong JavaScript như phương thức exec và test của RegExp, hay phương thức match, replace, search, và split của String. Ở phạm vi bài viết này, ta cùng tìm hiểu chi tiết hơn về biểu thức chính quy trong JavaScript.
Nội dung chính
Show
- I. Giới thiệu
- II. Tạo một biểu thức chính quy
- III. Cách viết một mẫu biểu thức chính quy
- mẫu /ab*c/ có thể tìm các đoạn có chứa: một kí tự ‘var re = new RegExp(“ab+c”);
5, theo sau là không có hoặc có một hoặc có nhiều kí tự var re = new RegExp(“ab+c”);
6, cuối cùng là một kí tự var re = new RegExp(“ab+c”);
7 như chuỗi var re = new RegExp(“ab+c”);
8 sẽ được khớp với xâu con var re = new RegExp(“ab+c”);
9.
II. Tạo một biểu thức chính quy
Ta có thể tạo biểu thức chính quy theo 2 cách sau:
-
Sử dụng cách mô tả chính quy thuần (regular expression literal):
var re = /ab+c/;
Các đoạn mã chứa các mô tả chính quy thuần sau khi được nạp vào bộ nhớ sẽ dịch các đoạn mô tả đó thành các biểu thức chính quy. Các biểu thức chính quy được dịch ra này sẽ được coi như các hằng số, tức là không phải tạo lại nhiều lần, điều này giúp cho hiệu năng thực hiện tốt hơn.
-
Tạo một đối tượng
var re = new RegExp("ab+c");
0 :
var re = new RegExp("ab+c");
Với cách này, các biểu thức chính quy sẽ được dịch ra lúc thực thi chương trình nên hiệu năng không đạt được như với việc sử dụng cách mô tả chính quy thuần. Nhưng ưu điểm là nó có thể thay đổi được, nên ta thường sử dụng chúng khi ta muốn nó có thể thay đổi được, hoặc khi ta chưa chắc chắn về các mẫu chính quy (pattern) chẳng hạn như khi nhập từ bàn phím.
III. Cách viết một mẫu biểu thức chính quy
Một mẫu biểu thức chính quy là một tập các kí tự thường, như /abc/, hay một tập kết hợp cả kí tự thường và kí tự đặc biệt như /ab*c/ hoặc /Chapter (\d+).\d*/ . Trong ví dụ cuối có chứa cả các dấu ngoặc đơn( () )được sử dụng như các thiết bị nhớ, tức là các mẫu trong phần
var re = new RegExp("ab+c");
1 này sau khi được tìm kiếm có thể được nhớ lại để sử dụng cho các lần sau./abc/, hay một tập kết hợp cả kí tự thường và kí tự đặc biệt như /ab*c/ hoặc /Chapter (\d+).\d*/ . Trong ví dụ cuối có chứa cả các dấu ngoặc đơn( () )được sử dụng như các thiết bị nhớ, tức là các mẫu trong phần
var re = new RegExp("ab+c");
1 này sau khi được tìm kiếm có thể được nhớ lại để sử dụng cho các lần sau.
1. Sử dụng mẫu đơn giản
Các mẫu đơn giản là các mẫu có thể được xây dựng từ các kí tự có thể thể tìm kiếm một cách trực tiếp.
Ví dụ:
mẫu
var re = new RegExp("ab+c");
2 sẽ tìm các các đoạn
var re = new RegExp("ab+c");
3 theo đúng thứ tự đó trong các chuỗi. Mẫu này sẽ khớp được với “Hi, My name is abc.” và “I am from abcdef city.”, vì cả 2 chuỗi này đều chứa đoạn ‘abc’. Còn với chuỗi
var re = new RegExp("ab+c");
4, nó sẽ không khớp vì chuỗi này không chứa abc theo đúng thứ tự, mà chỉ chứa ab c.
2. Sử dụng các kí tự đặc biệt
Các mẫu có thể chứa các kí tự đặc biệt cho các mục đích tìm kiếm nâng cao mà tìm kiếm trực tiếp sẽ khó khăn. Thí dụ như tìm một đoạn chứa một hoặc nhiều hơn một kí tự b, hay tìm một hoặc nhiều kí tự dấu cách (while space).
Ví dụ:
mẫu
var re = new RegExp("ab+c");
2 sẽ tìm các các đoạn
var re = new RegExp("ab+c");
3 theo đúng thứ tự đó trong các chuỗi. Mẫu này sẽ khớp được với “Hi, My name is abc.” và “I am from abcdef city.”, vì cả 2 chuỗi này đều chứa đoạn ‘abc’. Còn với chuỗi
var re = new RegExp("ab+c");
4, nó sẽ không khớp vì chuỗi này không chứa abc theo đúng thứ tự, mà chỉ chứa ab c./ab*c/ có thể tìm các đoạn có chứa: một kí tự ‘
var re = new RegExp("ab+c");
5, theo sau là không có hoặc có một hoặc có nhiều kí tự
var re = new RegExp("ab+c");
6, cuối cùng là một kí tự
var re = new RegExp("ab+c");
7 như chuỗi
var re = new RegExp("ab+c");
8 sẽ được khớp với xâu con
var re = new RegExp("ab+c");
9.
2. Sử dụng các kí tự đặc biệt
Các mẫu có thể chứa các kí tự đặc biệt cho các mục đích tìm kiếm nâng cao mà tìm kiếm trực tiếp sẽ khó khăn. Thí dụ như tìm một đoạn chứa một hoặc nhiều hơn một kí tự b, hay tìm một hoặc nhiều kí tự dấu cách (while space).
mẫu /ab*c/ có thể tìm các đoạn có chứa: một kí tự ‘
var re = new RegExp("ab+c");
5, theo sau là không có hoặc có một hoặc có nhiều kí tự
var re = new RegExp("ab+c");
6, cuối cùng là một kí tự
var re = new RegExp("ab+c");
7 như chuỗi
var re = new RegExp("ab+c");
8 sẽ được khớp với xâu con
var re = new RegExp("ab+c");
9.
Ví dụ:
mẫu
var re = new RegExp("ab+c");
2 sẽ tìm các các đoạn
var re = new RegExp("ab+c");
3 theo đúng thứ tự đó trong các chuỗi. Mẫu này sẽ khớp được với “Hi, My name is abc.” và “I am from abcdef city.”, vì cả 2 chuỗi này đều chứa đoạn ‘abc’. Còn với chuỗi
var re = new RegExp("ab+c");
4, nó sẽ không khớp vì chuỗi này không chứa abc theo đúng thứ tự, mà chỉ chứa ab c.
2. Sử dụng các kí tự đặc biệt
Các mẫu có thể chứa các kí tự đặc biệt cho các mục đích tìm kiếm nâng cao mà tìm kiếm trực tiếp sẽ khó khăn. Thí dụ như tìm một đoạn chứa một hoặc nhiều hơn một kí tự b, hay tìm một hoặc nhiều kí tự dấu cách (while space).
mẫu /ab*c/ có thể tìm các đoạn có chứa: một kí tự ‘var re = new RegExp(“ab+c”);
5, theo sau là không có hoặc có một hoặc có nhiều kí tự var re = new RegExp(“ab+c”);
6, cuối cùng là một kí tự var re = new RegExp(“ab+c”);
7 như chuỗi var re = new RegExp(“ab+c”);
8 sẽ được khớp với xâu con var re = new RegExp(“ab+c”);
9.
Bảng dưới đây mô tả đầy đủ các kí tự đặc biệt có thể dùng với biểu thức chính quy.
3. Sử dụng ngoặc tròn
var
myRe =
/
d
(
b+
)
d/
g;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
Ngoặc tròn bao quanh bất kỳ phần nào của biểu thức chính quy sẽ khiến phần kết quả so khớp được nhớ. Mỗi lần nhớ, chuỗi con có thể được gọi lại để sử dụng, mô tả trong
var
myRe =
/
d
(
b+
)
d/
g;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
0.
var
myArray =
/
d
(
b+
)
d/
g.
exec
(
"cdbbdbsbz"
)
;
mẫu /Chapter (\d+).\d*/ khớp đúng với ‘Chapter ‘ theo sau bởi một hoặc nhiều kí tự số, sau nữa là một dấu chấm thập phân, cuối cùng có thể là 0 hoặc nhiều kí tự số. Bên cạnh đó, dấu ngoặc tròn được sử dụng để nhớ một hoặc nhiều kí tự số đầu tiên được khớp.
var
myRe =
new
RegExp
(
"d(b+)d"
,
"g"
)
;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
Mẫu này được tìm thấy trong chuỗi “Open Chapter 4.3, paragraph 6”, nhớ ‘4’ nhưng không được tìm thấy trong chuỗi “Chapter 3 and 4”, bởi vì chuỗi đó không có dấu chấm sau kí tự số ‘3’.
Để so khớp một chuỗi con không nhớ, đặt ?: ở vị trí đầu tiên trong ngoặc. Ví dụ, (?:\d+) khớp với một hoặc nhiều kí tự số nhưng không nhớ kết quả so khớp.
var
myRe =
/
d
(
b+
)
d/
g;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
console.
log
(
"The value of lastIndex is "
+
myRe.
lastIndex)
;
Kết quả hiển thị là :
The value of lastIndex is 5
Tuy nhiên nếu bạn chạy:
var
myArray =
/
d
(
b+
)
d/
g.
exec
(
"cdbbdbsbz"
)
;
console.
log
(
"The value of lastIndex is "
+
/
d
(
b+
)
d/
g.
lastIndex)
;
Thì kết quả hiển thị sẽ là:
The value of lastIndex is 0
Sự xuất hiện của /d(b+)d/g trong 2 lệnh trên là những đối tượng biểu thức chính quy khác nhau và vì thế có những giá trị khác nhau cho thuộc tính lastIndex. Nếu bạn cần truy cập những thuộc tính của một biểu thức chính quy, bạn nên gán nó tới một biến.
Sử dụng nhiều dấu ngoặc tròn
Sử dụng nhiều ngoặc tròn trong một biểu thức chính quy cho ta nhiều kết quả so khớp tương ứng được nhớ. Cho ví dụ, /a(b)c/ khớp với ‘abc’ và nhớ ‘b’. Để gọi lại những kết quả so khớp, sử dụng những phần tử của mảng [1]…, [n].
Số lượng các chuỗi con trong những ngoặc tròn là không giới hạn. Mảng trả về giữ lại tất cả mọi thứ được tìm thấy.
Ví dụ:
Đoạn mã JavaScript dưới đây sử dụng phương thức
var
myRe =
/
d
(
b+
)
d/
g;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
8 để giao hoán các từ trong chuỗi. Trong chuỗi thay thế, ta dùng
var
myRe =
/
d
(
b+
)
d/
g;
var
myArray =
myRe.
exec
(
"cdbbdbsbz"
)
;
9 và
var
myArray =
/
d
(
b+
)
d/
g.
exec
(
"cdbbdbsbz"
)
;
0 để chỉ các chuỗi khớp với mẫu trong ngoặc ở vị trí thứ 1 và 2.
var
re =
/
(
\w+
)
\
s(
\w+
)
/
;
var
str =
"John Smith"
;
var
newstr =
str.
replace
(
re,
"
$2
, $1
")
;
console.
log
(
newstr)
;
Kết quả hiển thị là: “Smith, John”.
Bài viết được dịch và tham khảo từ đây