Biểu thức chính quy (regular expression)


tự học php nâng cao 04/08/2015 Cùng chuyên mục

Biểu thức chính quy (regular express hay viết tắt là regexp, regex) 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.

Để sử dụng được biểu thức chính quy trong php bạn cần phải bật extention PCRE.
Hàm pre_match() - dùng để so sánh xem chuỗi kiểm tra có khớp với mẫu (pattern)
- hàm này hay được dùng với biểu thức chính quy. Ngoài ra còn có hàm pre_replace()
- dùng để tìm kiếm và thay thế chuỗi theo mẫu.

Cú pháp chuỗi mẫu (pattern syntax):

Ký tự thông thường (Literal Characters):

Đây là regex cơ bản nhất - chỉ bao gồm các ký tự alpha bet (a-z A-Z)
Ví dụ: So khớp mẫu 'php' trong chuỗi 'php is simple':

<?php
$str = 'php is simple';
$pattern = '/php/';
preg_match($pattern,$str,$match);
//trả ra mẫu so khớp nếu chuỗi có chứa đoạn chuỗi khớp với mẫu
echo $match[0]; //trả ra php
?>

Lưu ý: có phân biệt chữ hoa và chữ thường, mẫu 'php' khác 'Php'

Ký tự đặc biệt (Special Characters):

Biểu thức chính quy cho phép sử dụng các ký tự đặc biệt để phục vụ cho việc
tìm kiếm - so khớp - thay thế chuỗi theo các quy tắc phức tạp. Các ký tự
[ \ ^ $ . | ? * + ( ) - có ý nghĩa đặc biệt, được gọi là metacharacter.
Dưới đây là bảng các ký tự đặc biệt và ý nghĩa:

Ký tự Ý nghĩa
\ Bỏ đi ý nghĩa của ký tự đặc biệt (để nó trở thành 1 ký tự thoát escape character). Ví dụ:
\/ - không coi ký tự / là ký tự đặc biệt-bây giờ nó như là một ký tự thông thường.
. So khớp đúng 1 ký tự - ngoại trừ ký tự xuống dòng.
Ví dụ: preg_match('/./', 'PHP 5',$match);
giá trị $match:
Array(
[0] => P
)
^ Bắt đầu bằng chuỗi mẫu:
'/^ghi/' sẽ khớp với 'ghik', 'ghi' nhưng không khớp với 'fghi'
+ Khớp với lớp ký tự trước đó - xuất hiện 1 hoặc nhiều lần:
'/a+b/' sẽ khớp với 'ab' 'aab' 'aaab' nhưng không khớp với 'b'
$ Khớp với lớp ký tự kết thúc chuỗi (ngoại trừ ký tự kết thúc dòng):
'/$php/' khớp với 'is php' và 'is php\n' nhưng không khớp với chuỗi 'php is'
[...] Lớp ký tự (nhiều ký tự dùng để so khớp):
'/gr[ae]y/' sẽ khớp với 'gray' 'grey' - nghĩa là chỉ lấy 1 ký tự để so khớp.
Có thể sử dụng các ký tự đặc biệt khác trong lớp ký tự như ^ + . 
Ví dụ:
preg_match('/[0-9]+/','Nam 2015',$match);
Gía trị $match:
array(
[0] => 2015
);
[0-9] - là các ký tự số 0 1 2 3 4 ... 9, ký tự đặc biệt + biểu thị sẽ xuất nhiều nhiều lần

{m}
{m,n}
{m} độ dài m ký tự - {m,n} độ dài từ m -> n ký tự
Ví dụ:
'/tre{1,2}f/' khớp với 'tref'và 'treef', nhưng không khớp với 'treeef'
(...)

Tạo ra một mẫu con (sub pattern). Ví dụ:
regex: '/([12][0-9])([0-9]{2})/'
Sẽ tạo ra 2 mẫu:
([12][0-9]) - khớp với các số từ 10 -> 29
([0-9]{2}) - (số nguyên 2 chữ số)

preg_match(
'/([12][0-9])([0-9]{2})/',
'PHP in 2005.',
$match
);

Biến $match sẽ là:

Array
(
[0] => 2005
[1] => 20
[2] => 05
)

Một số mẫu hay dùng:

[0-9] - là các ký tự số 0 1 2 3 4 ... 9
+ [a-z] - các ký tự thường trong bảng chữ cái
+ [A-Z] - các ký tự hoa trong bảng chữ cái
+ [a-zA-Z] - các ký tự trong bảng chữ cái không phân biệt hoa hay thường

Ký tự viết tắt (Shorthand Character Classes):

\d là dạng viết tắt của [0-9]
\w là dạng viết tắt của [a-zA-Z]
\s là ký tự trắng (white space)
\D là phủ định của \d - nghĩa là các ký tự ngoại trừ ký tự số
\W là dạng phủ định của \w - nghĩa là các ký tự ngoại trừ ký tự trong bảng chữ cái
\S là các ký tự ngoại trừ ký tự trắng

Tách lấy số trong chuỗi:

<?php
$str = "chuoi bao gom so 124";
$pattern = "/[0-9]+/";
preg_match($pattern,$str,$match);
print_r($match);
preg_match_all($pattern,$str,$match);
print_r($match);
?>

Lưu ý: hàm preg_match() - chỉ lấy ra một chuỗi so khớp tính từ bên trái hàm preg_match_all() - lấy tất cả các chuỗi so khớp tính từ bên trái

 Ví dụ, dùng hàm preg_replace():

Dùng hàm preg_replace(), thay thế chuỗi red = do, green = xanh, yellow = vang

<?php
$string = 'Mau red green yellow'.';
$patterns = array();
$patterns[0] = '/red/';
$patterns[1] = '/green/';
$patterns[2] = '/yellow/';
$replacements = array();
$replacements[2] = 'do';
$replacements[1] = 'xanh';
$replacements[0] = 'vang';
echo preg_replace($patterns, $replacements, $string);
?>

Ở ví dụ trên, có thể sử dụng hàm str_replace() - tuy nhiên điểm mạnh của hàm preg_replace() là có thể sử dụng biểu thức chính quy.

TỔNG KẾT

Biểu thức chính quy có rất nhiều sức mạnh nhưng 'nó khá phức tạp'.




Bình luận:


php