Bài 05: Hàm tích hợp với Regexp PHP

1. Hàm preg_match() Hàm preg_match() được dùng để kiểm tra, so khớp và lấy kết quả của việc so sánh chuỗi dựa vào biểu thức chính quy Regular Expression, hàm này có ba tham số và có cú pháp như sau: preg_match ( $pattern , $subject, &$matches) Trong đó: $pattern là biểu thức Regular ...

1. Hàm preg_match()

Hàm preg_match() được dùng để kiểm tra, so khớp và lấy kết quả của việc so sánh chuỗi dựa vào biểu thức chính quy Regular Expression, hàm này có ba tham số và có cú pháp như sau:

preg_match ( $pattern , $subject, &$matches)

Trong đó:

  • $pattern là biểu thức Regular Expression
  • $subject là chuỗi cần kiểm tra
  • $matches là kết quả trả về, đây là một tham số truyền vào ở dạng tham chiếu.

Kết quả:

  • Kết quả của hàm preg_match() sẽ trả về TRUE nếu so khớp và FALSE nếu không khớp.

Ví dụ: kiểm tra một chuỗi có phải là một dãy số hay không

$pattern = '/^[0-9]+$/';
$subject = '0979306603';
if (preg_match($pattern, $subject, $matches)){
    echo 'Đây là một dãy số';
}

  Run

Ví dụ: Nhận giá trị trả về của biến $matches.

$subject = "www.chisephp.net";
$pattern = '/net/';
preg_match($pattern, $subject, $matches);
print_r($matches);

  Run

2. Hàm preg_match_all()

Hàm preg_match_all() so khớp tất cả sự xuất hiện của pattern trong chuỗi.

preg_match_all ($pattern, $subject, &$matches[,int $order])

Trong đó:

  • $partern là biểu thức Regular Expression
  • $subject là chuỗi muốn kiểm tra
  • $matches là biến lưu kết quả sau khi match

Hàm preg_match_all() nó sẽ đặt các so khớp này trong mảng $matches theo thứ tự bạn xác định bởi sử dụng tham số order tùy ý. Có hai kiểu order có thể là:

  • PREG_PATTERN_ORDER − là mặc định nếu tham số order tùy ý này không được bao. PREG_PATTERN_ORDER xác định thứ tự theo cách bạn có thể nghĩ về nó logic nhất; $matches[0] là một mảng tất cả các so khớp pattern hoàn chỉnh, $matches[1] là một mảng tất cả chuỗi so khớp với regexp được tham số hóa đầu tiên và cứ tiếp tục như vậy.

  • PREG_SET_ORDER − sẽ xếp thứ tự mảng khác một chút với cài đặt mặc định. $matches[0] sẽ chứa các phần tử được so khớp bởi regexp được tham số hóa đầu tiên, $matches[1] sẽ chứa phần tử được so khớp bởi regexp được tham số hóa thứ hai, và cứ tiếp tục như vậy.

Ví dụ:

<?php
	$subject = "Name: <b>Cristiano Ronaldo</b> <br> Club: <b>Real Madrid</b>";
	preg_match_all ("/<b>(.*)</b>/U", $subject, $matches);
	print_r('<pre>');
	print_r($matches);
	print_r('</pre>');
?>

  Run

3. Hàm preg_replace()

Hàm preg_replace() hoạt động giống như ereg_replace(), ngoại trừ việc regular expression có thể được sử dụng trong pattern và các tham số đầu vào thay thế.

Cú pháp:preg_replace ( $pattern, $replacement, $subject)

Trong đó:

  • $partern: là chuỗi Regular Expression
  • $replacement: là chuỗi replace thành
  • $subject: là string muốn duyệt và replace

Kết quả trả về của hàm preg_replace là chuỗi đã được replace.

Ví dụ: Replace ngôn ngữ lập trình PHP bằng MySQL

$partern = '/php/i';
$subject = 'Học lập trình PHP';
$replace= 'MySQL';
echo preg_replace($partern, $replace, $subject);

  Run

Lưu ý: Ký tự i trong biểu mẫu trên là một Modifier nó hành động so khớp mà không phân biệt chữ hoa và chữ thường.

Ví dụ: Mình có một chuỗi như sau:

<h1>Đây là thẻ H1</h1>, <h2>Đây là thẻ H2</h2>, <h3>Đây là thẻ H3</h3>

Hãy sử dụng Regular Expression xóa tất cả những thẻ h1,h2,h3 trong chuỗi.

Nhìn vào chuỗi trên bạn thấy mỗi cặp thẻ bao gồm cả thẻ mở và  thẻ đóng. Mình sẽ nêu ra một vài cách sau.

Cách 1: Xóa từng cặp thẻ một.

<?php 
	$subject = '<h1>Đây là thẻ H1</h1>, <h2>Đây là thẻ H2</h2>, <h3>Đây là thẻ H3</h3> ';
	// H1
	$subject = preg_replace('/</?h1>/i', ', $subject);
	// H2
	$subject = preg_replace('/</?h2>/i', ', $subject);
    // H3
	$subject = preg_replace('/</?h3>/i', ', $subject);
	
	echo $subject;

?>

  Run

Cách này đáp ứng được yêu cầu của bài toán nhưng làm thế này thì dài quá. Có cách nào đơn giản và hiệu quả hơn nữa không? Chúng ta sẽ sử dụng phép gom nhóm đã học ở các bài trước để gom chúng thành một chuỗi $partern kết hợp.

Cách 2: Gom nhóm thành một chuỗi kết hợp

<?php 
	$subject = '<h1>Đây là thẻ H1</h1>, <h2>Đây là thẻ H2</h2>, <h3>Đây là thẻ H3</h3> ';
	$subject = preg_replace('/(</?h1>|</?h2>|</?h3>)/i', ', $subject);

	echo $subject;
?>

  Run

Ok. Nhìn đã gọn gàng rồi. Liệu có cách nào nữa tối ưu hơn không?

Cách 3: Bạn để ý thì thấy các dấu và các ký tự h là không đổi. Thay vì gom nhóm như trên giờ ta chỉ cần gom những cái gì thay đổi.

<?php 
	$subject = '<h1>Đây là thẻ H1</h1>, <h2>Đây là thẻ H2</h2>, <h3>Đây là thẻ H3</h3> ';
	$subject = preg_replace('/</?h(1|2|3)>/i', ', $subject);
    // Hoặc $subject = preg_replace('/</?h[1-3]>/i', ', $subject); 
	
	echo $subject;
?>

  Run

4. Hàm preg_split()

Hàm preg_split() hoạt động giống hàm split(), ngoại trừ việc regular expression được chấp nhận như là các tham số đầu vào cho pattern.

Cú pháp: array preg_split(string $pattern, string $subject [, int $limit = -1 [, int $flags = 0 ]] )

Trong đó: 

  • $partern: là chuỗi Regular Expression
  • $limit: Nếu tham số tùy ý limit được xác định, thì chỉ có số limit các chuỗi phụ được trả về.
  • $subject: là chuỗi muốn duyệt và cắt
  • $flags: có thể là bất kỳ tổ hợp nào trong các cái sau:

- PREG_SPLIT_NO_EMPTY − nếu được thiết lập, chỉ có các phần không trống sẽ được trả về bởi preg_split().

- PREG_SPLIT_DELIM_CAPTURE − nếu được thiết lập, biểu thức được tham số hóa trong pattern sẽ được bắt và trả về.

- PREG_SPLIT_OFFSET_CAPTURE − nếu được thiết lập, với mỗi so khớp xuất hiện thì string offset cũng sẽ được trả về.

Trả về giá trị

  • Trả về mảng các chuỗi sau khi chia một string ban đầu.

Ví dụ:

<?php 
	$ip = "192.168.167.123"; // một dãy số bất kỳ
	$result = preg_split ("/./", $ip); 
	var_dump($result);
?>

  Run

5. Hàm preg_grep()

Hàm preg_grep() tìm kiếm tất cả phần tử của $input array, trả về tất cả phần tử mà so khớp với regexp pattern

Cú pháp: array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )

Trong đó:

  • $pattern: Là chuỗi Regular expression.
  • $input: Là mảng đầu vào
  • $flag: Nếu thiết lập PREG_GREP_INVERT, hàm này trả về các phần tử của mảng đầu vào không phù hợp với chuỗi $pattern.

Ví dụ:

<?php 
	$array = array("23.32","22","12.009","23.43.43");
	$result = preg_grep("/^(d+)?.d+.d+$/",$array);
	print_r('<pre>');
	print_r($result);
	print_r('</pre>');
?>

  Run

6. Tổng kết.

Qua bài viết này mình tổng hợp một số hàm PHP tích hợp với Regular expression. Regular expression luôn luôn là một chủ đề khó dù là một người có nhiều kiến thức, năm kinh nghiệm. Nhưng việc gì tới sẽ phải tới trong quá trình làm việc không ít hoặc nhiều bạn sẽ phải gặp nó.

0