Tải bản đầy đủ (.pdf) (15 trang)

tiểu luận môn Nguyên lý các ngôn ngữ lập trình. Đề tài tìm hiểu biểu thức chính quy, thư viện chính quy trong NN Java, PHP.net

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (518.29 KB, 15 trang )

I.

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG

  

BÀI TẬP LỚN
NGUYÊN LÝ CÁC NGÔN NGỮ LẬP TRÌNH
Giáo viên hướng dẫn:

TS. Nguyễn Hữu Đức

Học viên thực hiện :

Trương Thảo Nguyên

CB120098

Vũ Đình Phú

CB120104

Nguyễn Thị Thùy Liên

CB120046

Lớp:

Công nghệ thông tin 2 (KT)


Chuyên ngành:

Công nghệ thông tin (KT)

Đề bài:

Biể u thức chính quy, thư việ n biể u thức chính quy trong
các ngôn ngữ lập trình Java, PHP, .NET

HÀ NỘI 11 – 2012


MỤC LỤC
1. Biểu thức chính quy ................................................................................................... 4
1.1. Khái niệm .........................................................................................................................4
1.2. Đặc điểm ..........................................................................................................................4
1.2.1. Ưu điểm.....................................................................................................................4
1.2.2. Nhược điểm ...............................................................................................................4
1.3. Lịch sử phát triển ..............................................................................................................4
1.4. Các kiến thức cơ bản về biểu thức chính quy ....................................................................5
1.4.1. Cách thức họat động của biểu thức chính quy ............................................................5
1.4.2. Kí tự thông thường và kí tự đặc biệt ...........................................................................6
1.4.2.1. Kí tự thông thường ..............................................................................................6
1.4.2.2. Kí tự đặc biệt ......................................................................................................6
1.4.3. Tìm kiếm theo vị trí ...................................................................................................7
1.4.3.1. Neo đầu và neo cuối chuỗi ..................................................................................7
1.4.3.2. Sử dụng ^ và $ để neo đầu và cuối 1 dòng ...........................................................8
1.4.3.3. Neo đầu và cuối chuỗi vĩnh cửu ..........................................................................8
1.4.4. Các lớp ký tự .............................................................................................................8
1.4.4.1. Lớp ký tự phủ định ..............................................................................................9

1.4.4.2. Metacharacter trong lớp ký tự .............................................................................9
1.4.4.3. Lớp ký tự viết tắt (Shorthand Character Classes) ............................................... 10
1.4.4.4. Lớp ký tự viết tắt phủ định (Negated Shorthand Character Classes) ................... 10
1.4.5. Biểu thức lặp theo độ dài ......................................................................................... 10
1.4.6. Phân nhóm ............................................................................................................... 11

2. Thư viện biểu thức chính quy trong ngôn ngữ lập trình PHP ............................... 11
2.1. Thư viện PCRE l(Perl-Compatible Regular Expressions). ........................................... 11
2.2. Các nhóm hàm của regular expression trong PHP ........................................................... 12
2.2.1. Tập các hàm preg ..................................................................................................... 12
2.2.1.1. Hàm preg_match .............................................................................................. 12
2.2.1.2. Hàm preg_match_all ........................................................................................ 12
2.2.1.3. Hàm preg_grep ................................................................................................ 13
2.2.1.4. Hàm preg_repalce ............................................................................................ 13


2.2.1.5. Hàm preg_ repalce _callback ........................................................................... 13
2.2.1.6. Hàm preg_split ................................................................................................. 13
2.2.2. Tập các hàm ereg ..................................................................................................... 14
2.2.2.1. Hàm ereg .......................................................................................................... 14
2.2.2.2. Hàm ereg_replace ............................................................................................. 14
2.2.2.3. Hàm split .......................................................................................................... 14
2.2.3. Tập các hàm mb_ereg .............................................................................................. 14

3. Tài liệu tham khảo ................................................................................................... 15


1. Biểu thức chính quy
1.1. Khái niệm
Biểu thức chính quy ( regular expression viết tắt là regexp, reges hay regxp) là một chuỗi

miêu tả một bộ các chuỗi khác, theo những quy tắc cú pháp nhất định.
1.2. Đặc điểm
1.2.1. Ưu điểm
 Giúp đơn giản hơn trong lập trình và quá trình xử lý văn bản. ( Thay vì cần đến hàng trăm
thủ tục để có thể trích xuất tất cả các địa chỉ email từ một số tài liệu, với regular expression
chỉ cần một số dòng lệnh hoặc thậm chí một dòng lệnh để làm việc này.
 Giúp tiết kiệm thời gian và công sức
1.2.2. Nhược điểm
 Gây phiền toái không mong muốn như: sử dụng một biểu thức chính quy không phù hợp với
biểu thức muốn tìm hoặc số văn bản tìm được với biểu thức chính quy đó không phù hợp.
1.3. Lịch sử phát triển
Nguồn gốc của biểu thức chính quy nằm ở lý thuyết tự động và lý thuyết ngôn ngữ hình thức,
cả hai đều là một phần của khoa học máy tính. Do vậy có thể nói thuật ngữ regular expression
xuất phát từ lý thuyết toán học và khoa học máy tính, nó phản ánh một đặc điểm của các biểu
thức toán học được gọi là chính quy (regularity).
Trong những năm 1950, nhà toán học Stephen Cole Kleene mô tả các mô hình này bằng cách
sử dụng các ký hiệu toán học của ông được gọi là tập chính quy.
Ngôn ngữ SNOBOL được sử dụng đầu tiên trong việc so khớp mẫu, nhưng nó cũng không
giống hoàn toàn với biểu thức chính quy. Sau đó Ken Thompson đã xây dựng các ký hiệu Kleene
vào trình soạn thảo QED để so khớp mẫu trong các file văn bản. Sau đó ông thêm khả năng này
vào trình soạn thảo Unix, mà cuối cùng đã trở thành công cụ tìm kiếm grep rất phổ biển được sử
dụng cho biểu thức chính quy (grep là một từ có nguồn gốc từ những lệnh của biểu thức chính
quy tìm kiếm: g/re/p viết tăt cho biểu thức chính quy). Kể từ đó nhiều biến thể của biểu thức
chính quy do Thompson đưa ra được sử dụng rộng rãi trong Unix và các hệ Unix-like bao gồm
cả expr, AWK, Emacs..


Biểu thức chính quy của Perl và Tcl được bắt nguồn từ thư viện regex viết bởi Henry
Spencer, mặc dù sau đó Perl đã mở rộng thư viện này để thêm nhiều tính năng mới. Philip Hazel
phát triển PCRE(Perl Compatible Regular Expressions – biểu thức chính quy tương thích Perl),

dựa trên biểu thức chính quy của Perl và được sử dụng trong nhiều công cụ hiện đại như PHP và
Apache HTTP Server. Một phần của những nổ lực trong việc thiết kế Perl6 là cải thiện, phát
triển biểu thức chính quy Perl tích hợp và tăng phạm vi và khả năng để cho phép định nghĩa
được các biểu hiện phân tích cú pháp. Kết quả cho ra đời mini-language gọi là Perl 6 được sử
dụng để định nghĩa cú pháp cũng như cung cấp mọt công cụ để lập trình bằng ngôn ngữ.
1.4. Các kiến thức cơ bản về biểu thức chính quy
1.4.1. Cách thức họat động của biểu thức chính quy
Regex engine là 1 bộ phận của phần mềm, chuyên để xử lý regex (so khớp mẫu với 1 chuỗi
nào đó). Có nhiều regex engine và chúng không hoàn toàn tương thích với nhau. Cú pháp regex
(flavor) của mỗi engine cũng có sự khác nhau. Chúng ta sẽ tập trung vào cú pháp regex được sử
dụng trong Perl 5, vì nó phổ biến nhất. Rất nhiều engine regex khác giống với engine sử dụng
trong Perl 5: engine nguồn mở PCRE (sử dụng trong rất nhiều ngôn ngữ lập trình, như PHP), thư
viện regex .NET,...
Hiểu được cách làm việc của regex engine sẽ giúp ta viết regex tốt hơn, dễ dàng hơn. Nó
giúp ta hiểu được tại sao 1 regex hoạt động không như mong muốn, và giúp tiết kiệm thời gian
phải mò mẫm khi viết các regex phức tạp.
Có 2 loại regex engine: text-directed engines, và regex-directed engines. Loại cú pháp regex
mà ta đang thảo luận ở đây thuộc loại regex-directed engines. Loại engine này phổ biến hơn bởi
nó có 1 số chức năng rất hữu dụng như: lazy quantifiers, backreferences,...
Có thể dễ dàng kiểm tra xem loại cú pháp đang sử dụng thuộc về engine nào qua việc kiểm
tra xem lazy quantifiers và backreferences có được hỗ trợ không. Hãy thử dùng biểu thức regex
regex|regex not vào chuỗi regex not xem sao. Nếu kết quả so khớp là regex, thì engine đang dùng
thuộc loại regex-directed. Nêu kết quả là regex not, thì engine thuộc loại text-directed. Trong các
VD ở các bài tiếp theo, ta sẽ phân tích cụ thể cách thức làm việc của regex engine, qua đó giúp
sử dụng regex hiệu quả nhất và tránh mắc lỗi.
Regex-directed engine luôn trả về kết quả so khớp bên trái nhất .


Thậm chí nếu 1 match tốt hơn có thể được tìm thấy nếu tiếp tục so khớp. Đây là điều cần ghi
nhớ. Regex-directed engine luôn bắt đầu so khớp với ký tự đầu tiên của chuỗi. Hãy lấy 1 .VD

đơn giản nhất để minh hoạ: ta dùng regex cat vào chuỗi He captured a catfish for his cat. Engine
sẽ bắt đầu so khớp dấu hiện đầu tiên trong regex là c với ký tự đầu tiên của chuỗi là H. Không
khớp. Vì vậy nó tiếp tục lần lượt so khớp với ký tự thứ 2 và 3 là e và space. Đều không khớp.
Đến ký tự thứ 4, c đã khớp với c. Xong, giờ engine bắt đầu so khớp dấu hiệu thứ 2 trong regex là
a với ký tự thứ 5 của chuỗi là a. Khớp. Nhưng đến dấu hiệu thứ 3 của regex là t thì không khớp
với ký tự thứ 6 của chuỗi là p. Lúc này engine ngộ ra rằng không thể tìm ra 1 match bắt đầu từ
ký tự thứ 4 của chuỗi. Vì vậy, nó bắt đầu lại công việc từ đầu, từ ký tự thứ 5 của chuỗi. Regex c
không khớp với a. Cứ tiếp tục như vậy cho đến ký tự thứ 15 của chuỗi, regex c đã khớp với c.
Engine lần lượt so khớp các dấu hiệu còn lại trong regex với các ký tự tiếp theo trong chuỗi: a
khớp a, t khớp t. Và như vậy 1 match đã được tìm thấy bắt đầu từ ký tự 15. Engine sẽ trả về kết
quả và ngừng luôn, không tiếp tục tìm xem còn match nào tốt hơn không (VD: cat ở cuối chuỗi)
1.4.2. Kí tự thông thường và kí tự đặc biệt
1.4.2.1. Kí tự thông thường
Regex cơ bản nhất chính là biểu thức bao gồm 1 ký tự thông thường, VD: a. Nó sẽ so khớp
với thực thể đầu tiên của ký tự đó trong chuỗi. VD nếu có chuỗi: LazyDog is a boy, nó sẽ so
khớp với ký tự a sau ký tự L. Regex này cũng có thể so khớp với ký tự a thứ 2 nếu ta điều khiển
regex engine tiếp tục tìm kiếm sau khi đã so khớp được 1 lần. Cũng như vậy, regex dog sẽ so
khớp với dog trong chuỗi LazyDog is not a dog. Regex này bao gồm 1 sêri 3 ký tự thông thường.
Engine sẽ hiểu biểu thức này là: tìm d, theo sau bởi o, theo sau bởi g.
Chú ý rằng regex engine mặc định phân biệt chữ hoa và chữ thường. Dog không so khớp với
dog.
1.4.2.2. Kí tự đặc biệt
Vì ta cần làm nhiều công việc phức tạp hơn là tìm kiếm 1 đoạn văn bản, cho nên phải trưng
dụng 1 vài ký tự để làm những nhiệm vụ đặc biệt. Trong cú pháp regex được thảo luận ở đây, có
11 ký tự mang ý nghĩa đặc biệt: [ \ ^ $ . | ? * + ( ). Chúng được gọi là các metacharacter.
Nếu cần dùng các ký tự này với ý nghĩa thông thường, ta phải giải phóng nó bằng \. VD nếu
cần so khớp 1+1=2, thì regex đúng sẽ là 1\+1=2. Chú ý rằng 1+1=2 cũng là regex đúng, nên sẽ
không báo lỗi, nhưng nó sẽ không cho ta kết quả như mong muốn. Regex 1+1=2 sẽ so khớp với



111=2 trong chuỗi 123+111=234, vì dấu + ở đây mang ý nghĩa đặc biệt. Nếu ta quên không giải
phóng ký tự đặc biệt ở những chỗ nó không được phép đứng thì sẽ gặp lỗi. VD: +1
Hầu hết các loại cú pháp regex đều coi { như 1 ký tự thông thường, trừ khi nó là 1 phần của
toán tử nhắc lại (repetition operator), VD: {1, 3}. Vì vậy ta không cần giải phóng ký tự này.
Ta chỉ dùng \ để giải phóng các ký tự đặc biệt, còn các ký tự khác thì không nên, vì \ cũng là
1 ký tự đặc biệt. \ khi kết hợp với 1 ký tự thông thường sẽ có ý nghĩa đặc biệt, VD: \d sẽ so khớp
với 1 chữ số từ 0 - 9.
Tất cả các loại cú pháp regex đều cho phép giải phóng 1 ký tự đặc biệt bằng \. Rất nhiều cú
pháp khác còn hỗ trợ kiểu giải phóng \Q... \E. Tất cả các ký tự nằm trong cặp \Q và \E sẽ được
coi như ký tự thông thường. VD: \Q*\d+*\E sẽ so khớp với đoạn văn bản *\d+* . Kiểu cú pháp
này được hỗ trợ bởi JGsoft engine, Perl, PCRE.
1.4.3. Tìm kiếm theo vị trí
1.4.3.1. Neo đầu và neo cuối chuỗi
Mỏ neo không so khớp với bất kỳ 1 ký tự nào. Thay vào đó, chúng so khớp với 1 vị trí trước,
sau hoặc giữa các ký tự. Chúng được sử dụng để "neo" biểu thức regex vào 1 vị trí để so khớp.
Dấu ^ khớp với vị trí ngay trước ký tự đầu tiên trong chuỗi. Áp dụng regex ^a cho chuỗi abc, ta
sẽ được a. ^b sẽ không có kết quả khi so khớp với abc, vì b không khớp với ký tự ngay sau vị trí
bắt đầu của chuỗi, vị trí được khớp bởi ^.
Tương tự như trên, $ khớp với vị trí ngay sau ký tự cuối cùng của chuỗi. c$ sẽ khớp với c
trong abc, trong khi a$ không khớp.
Khi sử dụng regex trong ngôn ngữ lập trình để kiểm định thông tin nhập vào từ người dùng,
sử dụng neo là rất quan trọng. VD nếu ta dùng \d+ để kiểm tra xem người dùng có nhập vào 1 số
nguyên hay không, kết quả trả về vẫn có thể là đúng thậm chí nếu người dùng nhập qsdf4ghjk,
bởi \d+ khớp với 4. Regex đúng ở đây phải là ^\d+$. Bởi vì vị trí đầu chuỗi phải được khớp trước
khi \d+ được khớp, và vị trí cuối chuỗi phải được khớp ngay sau đó, vì vậy chuỗi nhập vào nếu
muốn khớp với ^\d+$ thì chỉ có thể là 1 chuỗi các chữ số (dấu + là toán tử nhắc lại, dùng để nhắc
lại ký tự trước nó 1 hoặc nhiều lần)
Một chú ý khác là ta có thể dễ dàng mắc lỗi với ký tự trắng. Trong ngôn ngữ Perl chẳng hạn,
khi đọc vào 1 dòng từ 1 file text, ký tự line break cũng sẽ được lưu vào biến. Do đó trước khi



tiến hành kiểm định thông tin nhập vào, ta cần chặt bỏ các ký tự trắng đầu và cuối. ^\s+ khớp với
ký tự trắng đầu và \s+$ khớp với ký tự trắng cuối.
1.4.3.2. Sử dụng ^ và $ để neo đầu và cuối 1 dòng
Nếu chuỗi cần xử lý được viết trên nhiều dòng, như kiểu first line\nsecond line (\n là ký tự
line break), ta có thể muốn làm việc với từng dòng hơn là với cả chuỗi. Do đó, các regex engine
được thảo luận trong loạt bài này còn có thêm chức năng mở rộng ý nghĩa của các mỏ neo. ^ vừa
có thể khớp với vị trí đầu chuỗi (trước ký tự f trong VD trên), vừa có thể khớp với vị trí ngay sau
mỗi line break (giữa \n và s). Cũng như vậy, $ vừa có thể khớp với vị trí cuối chuỗi (sau ký tự e
cuối cùng), vừa có thể khớp với vị trí trước mỗi line break (giữa e và \n).
Trong ngôn ngữ lập trình, ta phải kích hoạt chức năng mở rộng này, được gọi là chế độ đa
dòng (multi-line mode). VD trong Perl, ta làm việc này bằng cách thêm m vào sau đoạn mã
regex, VD: m/^regex$/m;
1.4.3.3. Neo đầu và cuối chuỗi vĩnh cửu
\A sẽ chỉ khớp với vị trí đầu chuỗi, và \Z chỉ khớp với vị trí cuối chuỗi. Chúng không bao giờ
khớp ở vị trí các line break, thậm chí cả khi chế độ "multiline mode" được kích hoạt. Điều này
đúng cho tất cả các loại cú pháp regex được thảo luận trong bài này.
1.4.4. Các lớp ký tự
Sử dụng lớp ký tự, ta sẽ khiến regex engine chỉ chọn ra 1 ký tự để so khớp. Để sử dụng, ta
đặt các ký tự cần so khớp vào 2 dấu [ và ]. VD: để so khớp ký tự a hoặc e, ta dùng [ae]. Như vậy
biểu thức gr[ae]y sẽ khớp với gray hoặc grey.
Lớp ký tự chỉ so khớp với 1 ký tự đơn. Như vậy gr[ae]y sẽ không khớp với graay, graey,v.v...
Thứ tự các ký tự trong lớp không quan trọng. Kết quả trả về luôn giống nhau.
Để xác định 1 vùng ký tự trong lớp ký tự, ta sử dụng dấu - . VD: [0-9] so khớp với 1 chữ số
từ 0 - 9. Có thể sử dụng nhiều vùng ký tự hoặc kết hợp vùng ký tự với ký tự đơn. VD: [0-9a-fAF] so khớp với 1 chữ số hệ 16, không phân biệt chữ hoa, thường. [0-9a-fxA-FX] so khớp với 1
chữ số hệ 16 hoặc chữ cái X, không phân biệt chữ hoa, thường. Cũng như trên, thứ tự các vùng
không quan trọng.


1.4.4.1. Lớp ký tự phủ định

Đặt dấu ^ sau [ trong lớp ký tự sẽ phủ định lớp ký tự đó. Kết quả là lớp ký tự sẽ so khớp với
bất kỳ ký tự nào không nằm trong lớp ký tự đó. Lớp ký tự phủ định có thể so khớp với cả ký tự
line break.
Chú ý rằng lớp ký tự phủ định vẫn phải được so khớp với 1 ký tự. VD: q[^u] không phải là
"q không theo sau bởi u" mà là "q theo sau bởi 1 ký tự không phải u". Vì vậy nó sẽ không so
khớp với q trong chuỗi Iraq, và sẽ so khớp với q và space trong chuỗi Iraq is a country.
1.4.4.2. Metacharacter trong lớp ký tự
Trong lớp ký tự, các ký tự mang ý nghĩa đặc biệt hay metacharacter chỉ bao gồm: ] \ ^ -. Các
metacharacter nói ở phần trước khi đặt trong lớp ký tự sẽ chỉ được coi như ký tự thông thường,
và do đó không cần phải giải phóng. VD: để tìm ký tự * hoặc +, ta dùng [+*].
Để đặt ký tự \ vào trong lớp ký tự với nghĩa thông thường, cần giải phóng nó bằng 1 ký tự \
khác. VD: [\\x] sẽ khơp với ký tự \ hoặc x. Các ký tự ] ^ - nếu muốn dùng theo nghĩa thông
thường cũng phải được giải phóng bằng \ hoặc đặt nó ở vị trí mà nó sẽ không có ý nghĩa đặc biệt.
Ta nên dùng cách thứ 2 để biểu thức regex trông dễ nhìn hơn như sau:
Với ^, đặt nó ở bất kỳ chỗ nào trừ vị trí ngay sau [ . VD: [x^] sẽ khớp với x hoặc ^.
Với ], đặt nó ngay sau [ hoặc [^ . VD: []x] sẽ khớp với ] hoặc x. [^]x] sẽ khớp với bất kỳ ký tự
nào không phải là ] hoặc x.
Với -, đặt nó ngay sau [ hoặc [^ , hoặc ngay trước ]. VD: cả [-x] và [x-] đều so khớp với hoặc x.
Có thể sử dụng tất cả các ký tự không in được trong lớp ký tự giống như dùng chúng ngoài
lớp ký tự. VD: [$\u20AC] sẽ khớp với $ hoặc ký tự đồng euro (với giả định cú pháp regex đang
dùng hỗ trợ unicode).
JGsoft engine, Perl và PCRE còn hỗ trợ kiểu \Q...\E trong lớp ký tự để giải phóng 1 chuỗi ký
tự. VD: [\Q[-]\E] sẽ khớp với [ hoặc - hoặc ].
Cú pháp regex của POSIX lại xử lý \ trong lớp ký tự như 1 ký tự thông thường. Đồng nghĩa
với việc ta không thể dùng \ để giải phóng ] ^ -. Để làm việc này ta chỉ còn cách đặt chúng vào
các vị trí như trình bày ở trên. Ngoài ra điều này cũng đồng nghĩa với việc các cú pháp tắt
(shorthand, VD: \d) không còn hiệu lực.


1.4.4.3. Lớp ký tự viết tắt (Shorthand Character Classes)

\d là dạng tắt của [0-9].
\w được gọi là "ký tự từ" (word character). Chính xác những ký tự nào được khớp với nó
thay đổi tuỳ theo mỗi loại cú pháp regex. Trong tất cả các loại cú pháp, nó sẽ bao gồm [A-Za-z].
Trong hầu hết các loại cú pháp, nó cũng bao gồm cả dấu _ và chữ số.
\s được gọi là "ký tự trắng" (whitespace character). Nó khớp với ký tự nào thì cũng tùy thuộc
vào từng loại cú pháp. Trong kiểu cú pháp thảo luận ở đây, nó bao gồm [\t]. Nghĩa là \s sẽ khớp
với space hoặc tab. Trong hầu hết cú pháp , nó cũng bao gồm cả ký tự carriage return hoặc line
feed, nghĩa là [\t\r\n]. Một số cú pháp khác lại bao gồm thêm cả các ký tự không in được hiếm
khi dùng như vertical tab hoặc form feed.
Các lớp ký tự viết tắt có thể được dùng cả trong lẫn ngoài cặp []. VD: \s\d khớp với 1 ký tự
trắng theo sau bởi 1 chữ số. [\s\d] khớp với 1 ký tự đơn là 1 ký tự trắng hoặc 1 chữ số. Khi áp
dụng vào chuỗi 1 + 2 = 3, regex thứ 1 sẽ khớp với 2 (space và 2), trong khi regex thứ 2 sẽ khớp
với 1. [\da-fA-F] khớp với 1 chữ số hệ 16, giống như [0-9a-fA-F].
1.4.4.4. Lớp ký tự viết tắt phủ định (Negated Shorthand Character Classes)
\D tương đương [^\d]
\W tương đương [^\w]
\S tương đương [^\s]
1.4.5. Biểu thức lặp theo độ dài
Biểu thức chính quy sử dụng các ký hiệu + * ? để thể hiện việc lặp các ký tự theo độ dài.
-

Ký tự * : mang ý nghĩa lặp lại ký tự, nhóm ký tự trước nó từ 0 đến n lần

-

Ký tự + : mang ý nghĩa lặp lại ký tự, nhóm ký tựn trước nó từ 1 đến n lần

-

Ký tự ? : mang ý nghĩa lặp lại ký tự, nhóm ký tự trước nó 0 hoặc 1 lần.


-

Ngoài ra biểu thức chính quy còn cho phép quy định biểu thức lặp lại chính xác số lần.

-

{x}: Mang ý nghĩa lặp lại ký tự, nhóm ký tự trước nó đúng x lần

-

{x,y}: Mang ý nghĩa lặp lại ký tự, nhóm ký tự trước nó từ x đến y lần

-

{x,}: Mang ý nghĩa lặp lại ký tự, nhóm ký tự trước nó lớn hơn bằng x lần


1.4.6. Phân nhóm
Biểu thức chính quy sử dụng các ký tự mở ngoặc tròn ( và đóng ngoặc tròn ) để phân
nhóm các ký tự.
Ví dụ /([a-z0-9]+)@([a-z]+)/ : biểu diễn một biểu thức chính quy so khớp với các chuỗi ký tự
gồm các ký tự từ a đến z hoặc từ 0 đến 9 là một nhóm đứng liền nhau lặp lại ít nhất 1 lần theo
sau là ký tự @ tiếp theo là một nhóm ký tự từ a đến z lặp lại ít nhất 1 lần.

2. Thư viện biểu thức chính quy trong ngôn ngữ lập trình PHP
2.1. Thư viện PCRE l(Perl-Compatible Regular Expressions).
PCRE viết tắt cho Perl-Compatible Regular Expressions. Đây là tên của một thư viện mã
nguồn mở được viết bằng ngôn ngữ C bởi Phillip Hazel. Thư viện tương thích với hầu hết các
trình biên dịch C và các hệ điều hành. Nhiều người đã phát triển các thưc viện từ PCRE làm cho

nó tương thích với các ngôn ngữ lập trình khác. Ví dụ như một số Delphi component chỉ đơn
giản là hàm bao quanh thư viện PCRE biên dịch thành một thư việ Win32 DLL. Thư viện cũng
bao gồm nhiều phiên bản Linux được chia sẻ như thư viện .so và các file .h.
Các hàm preg PHP và các lớp REALbasic Regex được xây dựng dựa trên PCRE. PCRE thực
hiện gần như cú pháp biểu thức chính quy của Perl 5.8, chỉ có sự hỗ trợ các thuộc tính Unicode
với \p là không đầy đủ mặc dù hầu hết những phần quan trọng nhất đã được hỗ trợ.
Sử dụng PCRE rất đơn giản. Trước khi có thể sử dụng một biểu thức chính quy nó cần được
chuyển đổi sang định dạng nhị phân để cải thiện hiệu quả. Để làm được điều này cần phải gọi
hàm pcre_complie(). Hàm sẽ trả về một con trỏ đến các định dạng nhị phân. Bạn không thể làm
bất cứ điều gì với kết quả ngoại trừ việc sử dụng nó để thực hiện các hàm pcre khác.
Để sử dụng biểu thức chính quy, hàm pcre_exec() sử dụng con trỏ được trả về với hàm
pcre_complie(), mảng ký tự mà bạn muốn tìm kiếm và số các ký tự tỏng mảng. Bạn cũng cần
phải sử dụng con trỏ để xác định được mảng các số nguyên nơi mà hàm pcre_exec() sẽ lưu trữ
kết quả, cũng như chiều dài của mảng các số nguyên. Chiều dài của mảng phải bằng số lượng
của các nhóm mà bạn muốn hỗ trợ cộng thêm 1 sau đó nhân 3. Hàm sẽ trả về -1 nếu không tìm
thấy kết quả, ngược lại nó sẽ trả về số lượng các nhóm thỏa mãn cộng với 1. Nếu số lượng thỏa
mãn nhiều hơn kích thước của mảng kết quả trả về sẽ là 0. Hai số nguyên đầu tiên trong mảng
chứa vị trí bắt đầu của biểu thức được tìm thấy và số byte trong biểu thức được tìm thấy. Các cặp
số nghuyên chứa vị trí bắt đầu và chiều dài của các tham chiếu ngược. Vì vậy array[n*2] là các


vị trí bắt đầu của các chuỗi thỏa mãn biểu thức chính quy và các array[n*2+1] là độ dài tương
ứng của các chuỗi.
Thư viện PCRE chỉ hỗ trợ regex phù hợp, một công việc nó làm khá tốt và không cung cấp,
hỗ trợ cho việc tìm kiếm thay thế hay chia tách chuỗi….Tuy nhiên đây không phải vấn đề lớn khi
bạn có thể dễ dàng làm được điều đó qua việc viết code.
2.2. Các nhóm hàm của regular expression trong PHP
2.2.1. Tập các hàm preg
Tất cả các hàm preg yêu cầu bạn phải đặc tả biểu thức chính quy như là 1 chuỗi sử dụng cú
pháp Perl. Trong Perl, /regex/ định nghĩa 1 biểu thức chính quy. Trong PHP, nó trở thành

preg_match(‘/regex/’,$subject). Dấu ‘/’ là để nhận biết biểu thức chính quy, nếu biểu thức chính
quy cần có dấu ‘/’ thì phải thêm ‘\’ đằng trước.
Ví dụ: -> trong biểu thức chính quy phải viết là: ‘/http:\/\/dantri.com.vn/’
Không giống như C# hay Java, PHP không yêu cầu loại bỏ toàn bộ ‘\’ trong chuỗi biểu thức.
Nếu muốn thêm dấu ‘\’ như là 1 ký tự trong xâu PHP, bạn chỉ cần loại bỏ nó nếu nó được theo
sau bởi những ký tự khác, cái mà cần được loại bỏ. Trong xâu được bao bọc bởi dấu nháy đơn,
chỉ ký tự nháy đơn và ‘\’ cần được loại bỏ. Dó là lý do tại sao biểu thức chính quy ở trên đây,
chúng ta không cần phải dùng ‘\\’ để nhận biết dấu chấm (.). Để xác định chuỗi ‘\\’ trong php thì
biểu thức chính quy phải viết là ‘/\\\\/’.
Một vài các option trong biểu thức chính quy: /regix/x
-

x=i ->Không phân biệt chữ hoa, chữ thường

-

x=s -> lấy tất cả các ký tự

-

Ngoài ra còn 1 số giá trị khác như u,m,x.. nhưng ít được sử dụng.

2.2.1.1. Hàm preg_match
bool preg_match(string pattern, string subject [, array groups])
Hàm return true nếu biểu thức chính quy pattern matches với chuỗi subject. Mảng groups
dùng để lưu lại những chuỗi con được tìm thấy
2.2.1.2. Hàm preg_match_all
Int pareg_match_all(string pattern, string subject, array matches, int flags)



Hàm này sẽ lấ y toàn bộ các chuỗ i đúng với biể u thức chính quy củ a chuố i subject.
Tấ t cả các chuỗ i con tìm thấ y lưu trong mảng matches và có thể được sắ p xế p nế u
truyề n thêm biế n flag.
2.2.1.3. Hàm preg_grep
Array preg_grep (string pattern, array subjects)
Hàm trả về 1 mả ng chứa tấ t cả string trong mả ng subjects mà có thể được tìm thấ y,
so khớp với biể u thức chính quy pattern.
2.2.1.4. Hàm preg_repalce
Mixed preg_replace (mixed pattern, mixed replacement, mixed subject [, int limit])
Hàm trả về 1 string với tất cả các chuỗi được tìm thấy, so khớp đúng với biểu thức chính quy
pattern được thay thế bới chuỗi replacement.
2.2.1.5. Hàm preg_ repalce _callback
preg_replace_callback (mixed pattern, callback replacement,mixed subject[,int limit])
Hàm hoạt động giống hàm preg_replace nhưng khác ở tham số thứ 2. Hàm preg_regplace sẽ
thay thế đoạn ký tự được so khớp đúng với pattern bằng replacement còn hàm
preg_replace_callback thay vì thay thế bằng chuỗi replacement thì mỗi khi so khớp được chuỗi
ký tự thỏa mãn pattern nó sẽ gọi hàm callback repacement. Hàm callback sẽ được gọi mỗi khi
biểu thức chính quy được so khớp đúng, tham số của hàm callback có thể là một mảng hoạc các
chuỗi.
Callbacks cho phép bạn làm tìm kiếm mạnh mẽ và thay thế các hoạt động mà bạn không thể
làm với các biểu thức thông thường một mình.
Ví dụ: nếu bạn tìm kiếm cho regex(\ d +) \ + (\ d +), bạn có thể thay thế 2 +3 với 5 bằng cách
sử dụng Callback:
function regexadd($groups) {
return $groups[1] + $groups[2];
}
2.2.1.6. Hàm preg_split
Array preg_split (string pattern, string subject [, int limit])



Hàm thực hiện việc phân chia chuỗi subject thành các chuỗi thỏa mãn được so khớp đúng
với patterm và trả về một mảng các chuỗi phân tách được.
2.2.2. Tập các hàm ereg
Các hàm ereg yêu cầu bạn xác định biểu thức chính quy như một chuỗi, như bạn mong
muốn. ereg ('regex', "subject") kiểm tra nếu regex phù hợp với subject. Bạn nên sử dụng dấu
nháy đơn khi viết một biểu thức chính quy như là một chuỗi ký tự. Một số ký tự đặc biệt như dấu
$ và dấu gạch chéo ngược \ là ký tự đặc biệt trong chuỗi PHP, nhưng không phải trong một chuỗi
trích dẫn PHP.
Các hàm ereg không còn được hỗ trợ ở các phiên bản sau của PHP 5.3.0.
Các hàm preg được khuyến cáo chạy nhanh hơn so với các hàm ereg
2.2.2.1. Hàm ereg
int ereg (string pattern, string subject [, array groups])
Hàm ereg trả về độ dài của chuỗi được so khớp với pattern trong subject.
2.2.2.2. Hàm ereg_replace
string ereg_replace (string pattern, string replacement, string subject)
Hàm thay thế tất cả các đoạn ký tự thỏa mãn biểu thức chính quy pattern bằng chuỗi
replacement trong chuỗi subject.
2.2.2.3. Hàm split
array split (string pattern, string subject [, int limit])
Hàm chia chuỗ i subject thành mả ng các chuỗi thỏ a mãn biể u thức chính quy pattern.
2.2.3. Tập các hàm mb_ereg
Tập các hàm mb_ereg làm việc giống hoàn toàn với các thàm ereg chỉ khác ở một điểm duy
nhất đó là: Các hàm ereg chỉ thao tác so khớp biể thức chính quy và các chuỗi được tạo nên từ
các ký tự 8 bit, trong khi các hàm mb_ereg có thể làm việc với các ký tự nhiều hơn 1 byte ví dụ
như các ký tự tiếng Trung quốc được tạo từ 4 byte.


3. Tài liệu tham khảo
-


/>
-

Wikipedia

-

o/php.html



×