Tải bản đầy đủ (.docx) (13 trang)

Biểu thức chính quy thư viện hàm biểu thức chính quy trong PHP

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 (126.69 KB, 13 trang )

BIỂU THỨC CHÍNH QUY
THƯ VIỆN HÀM BIỂU THỨC CHÍNH QUY TRONG PHP
Phần 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 Khai báo

Regular expression là một phần của ngôn ngữ lập trình và các thư viện để hoạt
động và phát triển. Sau đây là khai báo sử dụng regular expression trong 2 ngôn ngữ lớn
là Java và C#:
- Với ngôn ngữ Java:
using java.util.regex;
- Với ngôn ngữ C#:
using System.Text.RegularExpressions;
Với những thư viện đã khai báo sử dụng. Chúng ta có thể thực hiện những công
việc thông thường của regular expression như tìm kiếm và thay thế bằng cách xây dựng
những cú pháp đặc biệt.
1.4.2


Cách thức hoạt độ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.3 Ký tự thông thường và ký tự đặc biệt
a. 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.
b. 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.4

Tìm kiếm theo vị trí

Neo đầu và 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.
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



\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;
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.5

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: [09a-fA-F] 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.
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.
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.
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].
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.6

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.7

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.



Phầ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.
a. 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
b. 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.
c. 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.
d. 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.
e. 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];
}
f.

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
a. 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.
b. 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.
c. 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.




×