06/04/2021, 14:46

Negative Và Positive Lookbehind trong Regular Expression - Học Regular Expression PHP

Lookbehind dùng để xác định sự chọn lựa ở phía trước của một chuỗi Regular Expression, gồm có 2 loại là Negative Lookbehind và Positive Lookbehind. Đây là một quy tắc rất hay sử dụng để xử lý chuỗi nên nếu bạn bỏ qua phần này là một sai lầm đấy. Để dễ hình dung tôi đưa ra một ví dụ nhé: ...

Lookbehind dùng để xác định sự chọn lựa ở phía trước của một chuỗi Regular Expression, gồm có 2 loại là Negative LookbehindPositive Lookbehind. Đây là một quy tắc rất hay sử dụng để xử lý chuỗi nên nếu bạn bỏ qua phần này là một sai lầm đấy.

Để dễ hình dung tôi đưa ra một ví dụ nhé:

Ví dụ 1: Hãy lấy tất cả những phần đuôi email của thehalfheart trong chuỗi thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com. Kết quả muốn lấy sẽ là @gmail.com@yahoo.com

Nếu dùng các quy tắc Regular Expression căn bản thì ta sẽ làm như sau:

$string = 'thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com';
preg_match_all('/@[^,]+/', $string, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>';

Kết quả:

Array
(
    [0] => Array
        (
            [0] => @gmail.com
            [1] => @facebook.com
            [2] => @yahoo.com
        )
)

Đây không phải là kết quả mong đợi của ta vì dư @facebook.com. Giờ nếu ta đưa luôn chuỗi thehalfheart vào chuỗi Regular Expression như thế nào? Ta cùng xem code nhé:

$string = 'thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com';
preg_match_all('/thehalfheart@[^,]+/', $string, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>';

Kết quả:

Array
(
    [0] => Array
        (
            [0] => thehalfheart@gmail.com
            [1] => thehalfheart@yahoo.com
        )
)

Kết quả đúng là trả về 2 email của thehalfheart nhưng lại dư chữ thehalfheart nên không đúng như yêu cầu đề bài.

Vậy giải pháp của ta là sử dụng Positive Lookbehind trong Regular Expression để đưa vào chuỗi RegEx, nhưng trước tiên ta xem cú pháp nó đã:

Positive Lookbehind

Cú pháp: (?<=)

Ý tưởng:

Ở bài toán Ví dụ 1 ta thấy thông tin cần lấy là phần đuôi của email có phần đầu là thehalfheart. Như vậy ta sẽ dùng Positive Lookbehind để chọn lựa, nếu nói tiếng việt thì thế này: Lấy phần đuôi của email có phần đầu bằng thehalfheart. Các bạn xem bài giải nhé:

$string = 'thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com';
preg_match_all('/(?<=thehalfheart)@[^,]+/', $string, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>';

Kết quả:

Array
(
    [0] => Array
        (
            [0] => @gmail.com
            [1] => @yahoo.com
        )
)

Thật tuyệt vời, kết quả như mong đợi =))

Giải thích:

Ở chuỗi partern trong đoạn code trên ta tôi đã đưa vào một đoạn Positive Lookbehind (?<=thehalfheart) nên hệ thống sẽ hiểu là bắt đầu bằng thehalfheart và vì chữ thehalfheart nằm trong phần Lookbehind nên nó không nằm trong kết quả trả về.

negative Lookbehind

Cú pháp: (?<!)

Ngược với Positive, Negative sẽ lựa chọn với điều kiện là không giống. Giờ ta sẽ làm một ví dụ cho nó xôn nha.

Ví dụ 2: Lấy phần đuôi của email không phải là thehalfheart trong chuỗi sau: thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com, room@Zaidap.com.net. Có nghĩa kết quả trả về là @facebook.com@Zaidap.com.net.

Bài giải:

$string = 'thehalfheart@gmail.com, Zaidap.com@facebook.com, thehalfheart@yahoo.com, room@Zaidap.com.net';
preg_match_all('/(?<!thehalfheart)@[^,]+/', $string, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>';

Kết quả:

Array
(
    [0] => Array
        (
            [0] => @facebook.com
            [1] => @Zaidap.com.net
        )

)

Ôi trời, kêt quả đúng rồi, sao hay thế nhỉ?

Giải thích:

Tương tự như giải thích phần Positive, chuỗi partern có một đoạn Negative Lookahead (?<!thehalfheart) nên hệ thống sẽ hiểu là lấy những email nào có phần đầu không phải là thehalfheart, và chữ thehalfheart nằm trong lookahead nên nó sẽ không có trong kết quả trả về.

Lời Kết

Qua 2 ví dụ trên căn bản các bạn cũng hình dung được phần nào rồi nhỉ, các bạn hãy làm theo ví dụ, tự ra đề và tự giải để thưởng thức thành quả của bài học Positive và Positive Lookahead Trong Regular Expressoin nhé.

Tạ Quốc Bảo

23 chủ đề

7270 bài viết

0