Học về hàm preg_match_all trong php

Học về hàm preg_match_all trong php là vấn đề được nhiều lập trình viên quan tâm, bởi những kiến thức trên trường lớp là không đủ, vì vậy bài Học về hàm preg_match_all trong php sẽ chia sẻ tới bạn nhiều thông tin hữu ích

Mọi người vẫn hỏi tôi về việc học lập trình nói chung và PHP nói riêng có cần năng khiếu hay quá khó để tiếp cận hay không. Thì tôi có thể trả lời rằng, học lập trình cũng như việc bạn học tiếng Anh hay bất kỳ một ngôn ngữ khác, bởi lập trình...là ngôn ngữ của máy tính, để máy tính đọc và máy tính thực hiện theo yêu cầu của mình, bạn thích là học được.

Hàm preg_match dùng để lấy kết quả theo biểu thức RegEx nhưng nó chỉ lấy đúng một kết quả duy nhất. Ví dụ bạn muốn lấy chuỗi 'Hoidapcode' trong chuỗi 'Hoidapcode và Hoidapcode và Hoidapcode' thì nó chỉ trả về đúng một giá trị 'Hoidapcode'. Vậy để lấy hết tất cả ba chữ thì phải làm thế nào? Ta sẻ sử dụng hàm preg_match_all.

1. Hàm preg_match_all trong PHP

Hàm preg_match_all cũng có chức năng giống như preg_match đó là so khớp và trả về kết quả của việc so khớp đó. Tuy nhiên vẫn có sự khác biệt đó là:

  • preg_match chỉ chỉ trả về một kết quả cho mỗi regex con.
  • preg_match_all sẽ trả về hết kết quả so khớp chứ không phải là kết quả đầu tiên như preg_match.

Ví dụ: lấy đoạn chuỗi bên trong cặp nháy kép của chuỗi 'xin chào "các bạn", chào mừng đến "Hoidapcode.com" '.

Sử dụng hàm preg_match:

Trong ví dụ này có hai chuỗi nằm trong cặp nháy kép đó là chuỗi 'các bạn' và chuỗi 'Hoidapcode.com'. Bây giờ ta sử dụng hàm preg_match để lấy xem kết quả thế nào.

$subject = 'Hello "Everybody", welcome to "hoidapcode.com"';
preg_match('/"(.+)"/', $subject, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>'; 

Kết quả sẽ là:

Array
(
    [0] => "Everybody", welcome to "hoidapcode.com"
    [1] => Everybody", welcome to "hoidapcode.com"
) 

Mục đích của ta chỉ lấy đoạn text bên trong cặp nháy kép, nhưng nó trả về dài quá :D. Lý do là nó duyệt từ dấu nháy đầu chuỗi cho đến cuối chuỗi nên kết quả mới như vậy, đây gọi là hiện tượng Greedy mà chúng ta đã học ở bài các quy tắc Regular Expression căn bản. Vậy để lấy đoạn text trong cặp dấu nháy thứ nhất thì ta phải thêm dấu ? đằng sâu dấu + của chuỗi partern trên, có ý nghĩa là lấy kết quả match đầu tiên (chống greedy).

$subject = 'Hello "Everybody", welcome to "hoidapcode.com"';
preg_match('/"(.+?)"/', $subject, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>'; 

Kết quả sẽ là:

Array
(
    [0] => "Everybody"
    [1] => Everybody
) 

Sử dụng hàm preg_match_all:

Như vậy các bạn thấy preg_match chỉ lấy được một kết quả duy nhất. Có cách nào lấy hết kết quả không? Để trả lời ta tìm hiểu hàm preg_match_all nhé.

  • Cú pháp: preg_match_all ($pattern, $subject, &$matches)
  • 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

Như ở ví dụ trên, tức là lấy tất cả các chuỗi bên trong cặp nháy kép của chuỗi 'xin chào "các bạn", chào mừng đến "Hoidapcode.com"'.

$subject = 'Hello "Everybody", welcome to "hoidapcode.com"';
preg_match_all('/"(.+?)"/', $subject, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>'; 

Kết quả là :

Array
(
    [0] => Array
        (
            [0] => "Everybody"
            [1] => "hoidapcode.com"
        )

    [1] => Array
        (
            [0] => Everybody
            [1] => hoidapcode.com
        )

) 

Kết quả nó trả về một mảng gồm 2 phần tử và giá trị của mỗi phần tử giống như hàm kết quả của hàm preg_match nên mình không giải thích thêm về phần này nhé.

Giờ bạn thay đổi chuỗi $subject = 'Hello "Everybody", welcome to "Hoidapcode.com", thanks for "like it"'. Bạn chạy và kết quả sẽ là:

Array
(
    [0] => Array
        (
            [0] => "Everybody"
            [1] => "hoidapcode.com"
            [2] => "like it"
        )

    [1] => Array
        (
            [0] => Everybody
            [1] => hoidapcode.com
            [2] => like it
        )

) 

Rất đơn giản đúng không nào. Bây giờ lấy kết quả thì có 2 lựa chọn:

  • Nếu lấy có dấu ngoặc thì chọn phần tử thứ nhất
  • Nếu lấy không có dấu ngoặc thì chọn phần tử thứ 2

Giải thích tại sao lại có 2 phần tử thì như bài trước, phần tử thứ nhất là toàn chuỗi toàn partern, phần tử thứ 2 là kết quả của đoạn RegEx (.+?).

2. Ví dụ hàm preg_match_all trong PHP

Mình sẽ đưa ra một ví dụ để các bạn thực hành như sau: Lấy tất cả nội dung bên trong tất cả thẻ div của một file html.

Ta có hai vấn đề cần quan tâm:

  • Để lấy tất cả các đoạn text trong tất cả thẻ div thì ta phải dùng đến hàm preg_match_all trong php.
  • Đoạn $pattern sẽ có dạng $pattern = '/<div>(.*?)<\/div>/'. Lưu ý phải có dấu ? nha bạn, vì có dấu ? thì máy sẽ hiểu là lấy từng kết quả chứ không phải duyệt hết chuỗi rồi lấy (gọi là Greedy, bạn quay lại bài trước để xem phần này nhé).
$subject = '<div>Div1</div><div>Div2</div><div>Div3</div>';
preg_match_all('/<div>(.*?)<\/div>/', $subject, $matches);
echo '<pre>';
var_dump($matches);
echo '</pre>'; 

Kết quả sẽ là:

array(2) 
{
  [0]=> array(3) 
    {
        [0]=> string(15) "Div1"
        [1]=> string(15) "Div2"
        [2]=> string(15) "Div3"
    }
  
  [1]=> array(3) 
    {
      [0]=> string(4) "Div1"
      [1]=> string(4) "Div2"
      [2]=> string(4) "Div3"
    }
}

3. Lời kết

Như vậy để lấy tất cả kết quả thì ta sử dụng hàm preg_match_all còn chỉ lấy một kết quả đầu tiên thì ta sử dụng hàm preg_match. Thực tế thì bạn sử dụng hàm preg_match_all để thay thế cho hàm preg_match cũng được bằng cách lấy phần tử đầu tiên, tuy nhiên cách này rất rườm rà nên tùy vào trường hợp mà sử dụng cho hợp lý.

Hy vọng với bài viết về Học về hàm preg_match_all trong php đã giải đáp giúp bạn phần nào về kiến thức lập trình PHP. Như tôi đã nói, ngôn ngữ lập trình không quan trọng bằng tư duy giải thuật, tư duy logic để giải quyết vấn đề.

Với những năm trước đây, lập trình viên là một cái nghề khó và kén chọn người học, đồng nghĩa với việc thu nhập hàng tháng của các lập trình viên luôn cao. Còn những năm gần đây, thì lập trình là môn học phổ thông, và ai cũng nên học một ngôn ngữ lập trình nào đó.

Nếu bạn còn bất kỳ câu hỏi nào trong việc học lập trình online, hãy gửi yêu cầu cho tôi qua email hoidapcode.com@gmail.com hoặc để lại comment bên dưới, tôi sẽ giải đáp trong vòng 24 giờ!

Blog hoidapcode.com là blog được tổng hợp tự động các bài học, thông tin về lập trình trên mạng internet. Nếu bạn có ý kiến hoặc đóng góp về bài viết này, hãy liên hệ với tôi!