Cú pháp hàm preg_match, preg_match_all

Hàm preg_match thi hành tìm theo biểu thức RegExp (xem cách viết biểu thức chính quy RegExp), cú pháp như sau:

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

Hàm này tìm trong $subject các chuỗi con phù hợp với mẫu $pattern là một biểu thức RegExp. Hàm tra về các kết quả:

  • 1 tìm thấy chuỗi phù hợp
  • 0 không có chuỗi phù hợp
  • false lỗi biểu thức RegEx

Cụ thể về các tham số của preg_match:

  • $pattern : là biểu thức RegExp để tìm kiếm. Viết biểu thức chính quy RegExp, trong PHP các hàm sử dụng RegExp thường các biểu thức này nằm trong cặp /../
  • $subject : Chuỗi nguồn để tìm kiếm
  • $matches : là mảng kết quả tìm kiếm được nếu có, trong đó $matches[0] là chuỗi đầy đủ tìm kiếm được. Các phần tử tiếp theo tương ứng với chuỗi phù hợp với các mẫu con trong $pattern

Để lấy tất cả các kết quả tìm thấy dùng preg_match_all

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

preg_match_all hàm này trả về giá trị là số lượng kết quả, và kết quả lưu tại $matches, nếu trả về false thì lỗi RegEx

Ví dụ hàm preg_match, preg_match_all

Trích xuất các địa chỉ email từ một văn bản

Cho một văn bản, kiểm tra xem trong văn bản đó có địa chỉ email hay không, nếu có thì lấy các địa chỉ email đó. Thực hiện ví dụ này dùng hàm preg_match (chỉ trích xuất được một địa chỉ email đầu tiên nó tìm thấy).


<?php

    // Đoạn văn bản cần trích xuất email
    $text = "Đây là địa chỉ 
             email userabcguest@xuanthulab.net.vn và 
             xyz@gmail.com cần trích xuất";

    /***
     Xây dựng mẫu - biểu thức RegEx, biểu thức này lưu ở biến $pattern
    
     ([^\s.]+)@((.[^\s]+)(\..[^\s]+))
        Là địa chỉ email, kết quả đầy đủ tìm được phù hợp lưu tại $matches[1]
        Trong mẫu này có chứa 2 mẫu con
        
        ([^\s.]+)
        Mẫu con này là nhóm ký tự không có khoảng trắng nó là chuỗi phía trước @ của địa chỉ email, 
        kết quả lưu ở $matches[2] Sau mẫu này đến ký tự @, tiếp đó đến

        ((.[^\s]+)(\..[^\s]+)
        Là domain, kết quả lưu ở $matches[3], mẫu này lại chứa 2 mẫu con nữa

          (.[^\s]+) 
          Domain cấp 2, kết quả lưu ở $matches[4], nối tiếp nó là domain cấp 1 theo mẫu

          (\..[^\s]+)
          Domain cấp 1 (như .vn, .com) kết quả lưu ở $matches[5]

      Như vậy nếu có kết quả trả về thì:
      $matches[1] - địa chỉ email đầy đủ
      $matches[2] - địa chỉ email không có domain
      $matches[3] - địa chỉ domain
      
      Mẫu trên đặt trong cặp / ... /im
      Ký hiệu im có nghĩa tìm trên nhiều dòng (m), không phân biệt chữ hoa/thường (i)      
    */
    $pattern = "/(([^\s.]+)@((.[^\s]+)(\..[^\s]+)))/im";

    $matches = null;
    $returnval = preg_match($pattern, $text, $matches);

    if ($returnval == 1)
    {
        $emailfull = $matches[1];
        $emailname = $matches[2];
        $domain = $matches[3];

        echo "Lấy được địa chỉ email:", PHP_EOL;
        echo "email đầy đủ: {$emailfull}", PHP_EOL;
        echo "   tên email: {$emailname}", PHP_EOL;
        echo "      domain: {$domain}", PHP_EOL;

    }
    else
    {
        echo "Không thấy địa chỉ email nào";
    }
?>

/***
Kết quả chạy

Lấy được địa chỉ email:
email đầy đủ: userabcguest@xuanthulab.net.vn
   tên email: userabcguest
      domain: xuanthulab.net.vn
*/

Trong trường hợp muốn lấy có nhiều hơn 1 địa chỉ email thì thay hàm preg_match bằng preg_match_all

<?php

    $text = "Đây là địa chỉ 
             email userabcguest@xuanthulab.net.vn và 
             xyz@gmail.com cần trích xuất";

    $pattern = "/(([^\s.]+)@((.[^\s]+)(\..[^\s]+)))/im";

    $matches = null;
    $returnval = preg_match_all($pattern, $text, $matches);


    if ($returnval !== false)
    {
      echo "Tìm thấy {#returnval} email:", PHP_EOL;
      if ($returnval > 0) {
        for ($i=0; $i < $returnval; $i++) { 
          echo "{$matches[0][$i]}", PHP_EOL;      
        }
      }
    }
    else
    {
        echo "Lỗi RegEx";
    }
?>
/***
Kết quả:
Tìm thấy {#returnval} email:
userabcguest@xuanthulab.net.vn
xyz@gmail.com
*/

Tìm địa chỉ URL trong chuỗi với preg_match_all

Ví dụ này tương tự như trên, dùng biểu thức chính quy RegEx với hàm preg_match_all để trích xuất các địa chỉ URI trong một văn bản

<?php
$text = 'Đây là địa chỉ website của tôi https://xuanthulab.net, 
         đọc trang https://xuanthulab.net/lap-trinh-php/ để xem tôi viết về PHP..';

$rsvalue = preg_match_all("/[[:alpha:]]+:\/\/[^<>[:space:]]+[[:alnum:]\/]/",$text, $out);
if ($rsvalue !== false && $rsvalue > 0)
{
  foreach($out[0] as $url) 
  {
      echo $url, PHP_EOL;
  }
}
?>


//OUT:
https://xuanthulab.net
https://xuanthulab.net/lap-trinh-php/

Lấy tên host (domain) từ URL với preg_match


<?
$url        = 'https://www.xuanthulab.net/bieu-thuc-chinh-quy-regexp.html';
$pattern    = '/^(https:\/\/|http:\/\/)?([^\/]+)/i';
preg_match( $pattern, $url, $matches );
$host = $matches[2];
echo "Host name is: " . $host;
echo "<br />";


preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "Domain name is: " . $matches[0];

?>
//OUT:
Host name is: www.xuanthulab.net
Domain name is: xuanthulab.net

 

Kiểm tra URL có đúng định dạng với preg_match


<?
function get_valid_url( $url ) {

    $regex = "((https?|ftp)\:\/\/)?";                                       // Scheme 
    $regex .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?";  // User and Pass
    $regex .= "([a-z0-9-.]*)\.([a-z]{2,3})";                                // Host or IP
    $regex .= "(\:[0-9]{2,5})?";                                            // Port
    $regex .= "(\/([a-z0-9+\$_-]\.?)+)*\/?";                                // Path
    $regex .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?";                   // GET Query
    $regex .= "(#[a-z_.-][a-z0-9+\$_.-]*)?";                                // Anchor

    return preg_match("/^$regex$/", $url);

}

    $url = "https://xuanthulab.net/server/";
    
    if( get_valid_url( $url ) ) 
    {
        echo "URL đúng chuẩn: " . $url;
    }
    else 
    {
        echo "URL sai: " . $url;
    }
?>
 

Kiểm tra password

Dùng biểu thức chính quy, kiểm tra passwod phải là chữ hoặc số, dài từ 8 đến 16 ký tự.

 
<?php
    $password = "abc";

    if (! preg_match("/[[:alnum:]]{8,16}/i", $password))
    {
        print "Password không đúng! Phải có độ dài 8 - 16 ký tự";
    }
    else
    {
        print "Valid password";
    }
?>