Hàm preg_match trong PHP

Các hàm này tận dụng sức mạnh của biểu thức chính quy (regex), và giúp chúng ta thực hiện được nhiều nhiệm vụ khá nhanh gọn.

Số lượng hàm preg không nhiều, hôm nay chúng ta sẽ tìm hiểu từng hàm một. Đầu tiên là preg_match


preg_match

Biểu thức đơn giản:

preg_match($pattern, $str)

Dùng để tìm mẫu $pattern có trong chuỗi $str hay không. Kết quả 1 là có, còn 0 nghĩa là không tìm thấy.

Ví dụ 1:

$str = "nguyễn đức anh";
$pt = '/mạnh/';
echo preg_match($pt,$str);

// sẽ trả về kết quả 0 vì mạnh không có trong chuỗi $str

Ví dụ 2:

$str = "nguyễn đức anh";
$pt = '/đức/';
echo preg_match($pt,$str);

// sẽ trả về kết quả 1 vì đức có trong chuỗi $str

Chúng ta lưu ý là mẫu so sánh cần phải đặt trong dấu / / nếu không là sẽ báo lỗi, và dù mẫu có thì cũng không trả về kết quả gì.

Ví dụ 3:

$str = "nguyễn đức anh";
$pt = 'đức';
echo preg_match($pt,$str);

// sẽ trả về thông báo lỗi Warning: preg_match(): No ending delimiter
// vì mẫu cần tìm không được đặt trong dấu //

Với biến chúng ta cần nối nó vào như dưới đây/

Ví dụ 4:

$str = "nguyễn đức anh";
$mid = 'đức'; // mẫu cần tìm
$pt = '/'.$mid.'/'; // nối nó vào dấu /
echo preg_match($pt,$str); // rồi bạn mới dùng hàm được

// kết quả trả về 1

Nếu bạn muốn so sánh không phân biệt chữ hoa chữ thường thì làm như sau.

Ví dụ 5:

$str = "Nguyễn Đức Anh";
$pt = '/anh/i';
echo preg_match($pt,$str);

// vẫn cho kết quả 1, dù mẫu là viết thường, còn chuỗi chỉ có từ Anh viết hoa đầu từ

Tuy nhiên điều này chỉ đúng với từ không dấu, còn từ có dấu thì không chính xác nữa.

Ví dụ 6:

$str = "Nguyễn Đức Anh";
$pt = '/đức/i';
echo preg_match($pt,$str);

// lại trả về kết quả 0

Vì thế thực tế chúng ta không nên xem i như là cách đáng tin cậy, mà vẫn nên chuyển chuỗi về dạng ký tự thống nhất, thường là viết thường để so sánh cho yên tâm. Hàm để chuyển chuỗi về dạng viết thường là mb_strtolower (xem thêm các hàm có tiền tố mb trong PHP)


Biểu thức đầy đủ của preg_match

Cú pháp:

preg_match(pattern, input, matches, flags, offset)

Giải thích các tham số:

Tham số Mô tả
patternCần phải có. Đây là biểu thức chính quy chỉ đến mẫu cần tìm
inputCần phải có. Đây chỉnh là chuỗi mà chúng ta dùng để tìm xem pattern có ở trong hay không
matchesTùy chọn (tức là có cũng được, không có cũng không sao). Biến được sử dụng trong tham số này sẽ được dùng để điền vào tất cả các mảng khớp. Chốc có ví dụ chúng ta sẽ dễ hiểu hơn.
flagsTùy chọn. Một tập hợp các tùy chọn dùng để thay đổi cách mảng so khớp được cấu trúc:

PREG_OFFSET_CAPTURE – Khi tùy chọn này được bật, mỗi lần so khớp phù hợp, thay vì trả về một chuỗi, sẽ là một mảng trong đó phần tử đầu tiên là một chuỗi con chứa kết quả phù hợp và phần tử thứ hai là vị trí của ký tự đầu tiên của chuỗi con trong đầu vào ($str).

PREG_UNMATCHED_AS_NULL – Khi tùy chọn này được bật, các mẫu con không khớp sẽ được trả về dưới dạng NULL thay vì dưới dạng chuỗi trống.
offsetTùy chọn. Hiện tôi không rõ chức năng của nó là gì.

Giờ chúng ta sẽ đi vào các ví dụ cụ thể để hiểu rõ hơn các tham số trên.

Ví dụ 7:

$str = "xin chào các bạn, với ví dụ này các bạn sẽ thấy dễ hiểu hơn";
$pt = '/bạn/';
echo preg_match($pt,$str,$matches)."<br>";
print_r($matches);

// kết quả:
// 1
// Array ( [0] => bạn )

Như vậy $matches sẽ là mảng chứa kết quả. Và mặc dù có 2 chữ bạn trong chuỗi $str, nó chỉ trả về kết quả khớp chứ không có thông tin cho biết có 2 mẫu $pt trong $str.

Giờ chúng ta thử thêm PREG_OFFSET_CAPTURE vào xem có gì khác không.

Ví dụ 8:

$str = "xin chào các bạn, với ví dụ này các bạn sẽ thấy dễ hiểu hơn";
$pt = '/bạn/';
echo preg_match($pt, $str, $matches, PREG_OFFSET_CAPTURE)."<br>";
print_r($matches);

// kết quả:
// 1
// Array ( [0] => Array ( [0] => bạn [1] => 15 ) )

Chúng ta thấy có thông báo vị trí của chuỗi con ($pt) cần tìm trong chuỗi lớn ($str). Tuy nhiên do ảnh hưởng của dấu, kết quả không chính xác, vị trí đúng phải là 13 chứ không phải 15. Các ký tự đặc trưng tiếng Việt sẽ bị vậy chứ không chỉ riêng từ có dấu, ví ă, â cũng sẽ bị cộng thêm.

Leave a Comment