Hướng dẫn dùng hack regex trong PHP
Chúng ta đã tìm hiểu cú pháp cơ bản của RegEx trong bài viết này, hôm nay tôi và các bạn sẽ tìm hiểu việc áp dụng nó trong PHP. Show
Tài liệu tham khảo dễ hiểu là W3School và các tài liệu khác tôi tìm thấy trên mạng. Trong phần đầu W3School định nghĩa Regular Expression (biểu thức chính quy) như thế này: Regex là một chuỗi các ký tự tạo thành mẫu tìm kiếm. Khi bạn tìm kiếm dữ liệu trong một văn bản (text), bạn có thể sử dụng mẫu tìm kiếm để mô tả bạn muốn tìm kiếm điều gì. Regex có thể là một ký tự hoặc một mẫu phức tạp hơn. Regex có thể được dùng để thực hiện tất cả các kiểu tìm kiếm văn bản và thay thế văn bản.
#1. Cú phápTrong PHP thì Regex là một chuỗi được tạo thành từ dấu phân cách, mẫu tìm kiếm và các tùy chọn khác. Ví dụ:
Trong ví dụ trên, Dấu phân cách có thể là bất kỳ ký tự nào, nhưng không được phép là chữ cái (a, b, c,…, x, y, z), số (0, 1, 2 ,…9), dấu gạch ngược (\) hoặc khoảng trắng. Dấu phân cách phổ biến nhất là dấu gạch xuôi (/), tuy nhiên nếu mẫu tìm kiếm của bạn bao gồm dấu gạch xuôi thì sẽ tiện lợi hơn nếu bạn chọn dấu phân cách khác, chẳng hạn như # hoặc ~. #2. Các hàm Regular ExpressionPHP cung cấp đa dạng các hàm cho phép bạn sử dụng biểu thức chính quy, trong đó các hàm
#3. Cách sử dụng preg_match()Hàm Ví dụ sử dụng regex để tìm kiếm mẫu “nguyễn” không phân biệt hoa thường trong chuỗi:
#4. Cách sử dụng preg_replace()Hàm Ví dụ tôi muốn thay thế từ sai chính tả
#5. Cách sử dụng preg_match_all()Hàm preg_match_all sẽ nói cho bạn biết có bao nhiêu lần mẫu tìm kiếm được tìm thấy trong chuỗi. Ví dụ tôi cần đếm số lần ký tự n xuất hiện trong một tên nào đấy, không phân biệt nó là hoa hay thường:
#6. Các tùy chọn điều chỉnh trong RegexCác tùy chọn điều chỉnh được dùng để yêu cầu một câu lệnh tìm kiếm thực hiện một kiểu tìm kiếm nhất định.
Nội dung chính Show
Regular Expression (RegEx) à? Nghe quen quen.
Bạn cần xử lý validate (kiểm tra tính hợp lệ) các trường dữ liệu nhập vào ô TextBạn cần copy và paste rất nhiều text từ chỗ này sang chỗ kiaVí dụ từ XML sang C# hoặc CSV, Excel sang C# Tìm kiếm một chuỗi nằm ở nhiều dòng trong Visual Studio hoặc Notepad++Ví dụ tôi cần tìm và xóa bỏ (replace all) các comment như thế này ở code cũ. Kiểm tra bằng câu lệnh SQL xem đã insert đủ các trường vào DB hay chưa?Bạn cần bóc tách dữ liệu của một trang web.Ví dụ extract (crawling) tách lấy dữ liệu từ một trang web để lưu lại vào cơ sở dữ liệu của bạn Cơn ác mộng đọc một chuỗi string từ DB và cố gắng chuyển đổi nó sang DateTimeChuỗi ngày tháng lưu vào CSDL rất đa dạng. Rất khó để dùng hàm DateTime.TryParse() để tự động chuyển đổi một chuỗi thành Datetime ngon lành cành đào. Tìm kiếm một chuỗi, lưu chuỗi đó lại và lấy chuỗi đã lưu chèn vào chỗ nào đóHay nói cách khác, ta cần thay một chuỗi bằng một chuỗi khác, trong chuỗi mới đó lại có chứa cả chuỗi vừa bị thay thế. Như ví dụ dưới đây sẽ cho các bạn thấy. Ta cần tìm ra ClassName, nhưng không phải thay thế ClassName đó bằng Class khác mà ta sẽ nhét nó vào 2 vị trí thay vì chỉ có 1 vị trí như hiện tại. Vậy RegEx có thể giúp gì cho chúng ta trong các trường hợp trên?Regular Expression sinh ra là để giúp cho cuộc đời của bạn bớt khổ. Hãy tưởng tượng xem bạn phải nai lưng ra copy-paste bao nhiêu code. Bạn hoàn toàn có thể download các tool về để replace giúp bạn. Nhưng bạn cần bao nhiêu tool cho đủ đây. Thay vào đó, bạn hãy thử học RegEx. Bộ cú pháp này sẽ giúp cho bạn thao
tác với chuỗi như dao chém chuối. Như ta thấy các ví dụ bên trên, tất cả đều là RegEx không phải là một ngôn ngữ lập trình. Nó chỉ là một Hãy lần lượt xem qua các ví dụ sau đây để học cách sử dụng Regular Expression nhé. Bắt đầu sử dụng Regular ExpressionĐể bắt đầu sử dụng và học cách dùng RegEx, mình hay dùng trang web https://regex101.com/. Giao diện như sau: Trước hết các bạn hãy đọc qua một lượt các quy tắc bắt chuỗi (matching) đơn giản nhất của RegEx
Đừng lo, hãy xem qua các ví dụ từ từ rồi bạn sẽ hiểu Ví dụ đơn giảnTìm chuỗi sốTìm ngày thángLink demo: https://regex101.com/r/3dNzjU/1 Tìm ngày tháng chính xácTrong ví dụ trên thì ta thấy có chuỗi "60/60/2018" cũng được coi là ngày tháng, như thế là không chính xác. Ta hãy viết lại cho chuẩn. Link demo: https://regex101.com/r/3dNzjU/2 Cách "tóm lấy" string cần tìm đưa vào GroupCách tạo ra code để dùng RegEx trong các ngôn ngữ lập trìnhRegEx là bộ cú pháp, tuy nhiên để áp dụng nó vào các ngôn ngữ lập trình lại phải tuân thủ theo các thư viện và quy tắc lập trình để lấy ra được các Group đã capture (thu) được. Hãy xem các tạo code ngay sau đây: Cách bắt lấy chuỗi bất kỳLink demo: https://regex101.com/r/3dNzjU/3Lấy một chuỗi nhưng không chứa 1 ký tự đặc biệt nào đóVí dụ bạn cần lấy 1 chuỗi dài, nhưng nếu chuỗi đó có chứa 1 ký tự đặt biệt nào đó, ví dụ ký tự Rất đơn giản, chúng ta hãy làm như sau để có thể loại bỏ dấu "/" ra khỏi kết quả thu được. https://regex101.com/r/ctuQwj/1 Giải thích 1 chút, như mình đã nói bên trên, khi dùng Bình thường nếu tìm một chuỗi dài liên tiếp, không quan tâm là ký tự hay chữ số, ta hay viết là Dấu chấm Sử dụng Lấy một chuỗi nhưng không chứa 1 chuỗi con đặc biệt nào đóBây giờ bạn không chỉ cần exclude (loại bỏ) một ký tự ra khỏi danh sách chuỗi thu được, bạn còn cần loại bỏ hẳn "một chuỗi" thì sao. Vậy hãy dùng cách sau đây: Vấn đề lúc này cần phải dùng đến chức năng Negative Lookahead của Regex, cách hoạt động như sau: Giả sử mình cần exclude (loại bỏ) một chuỗi (chứ không phải 1 ký tự như là ví dụ Vì chuỗi con nằm bên trong chuỗi cha, do đó chúng ta cần viết thêm 1 dấu chấm Như vậy để viết Regex này ta phải tư duy từ bên trong ra bên ngoài. Và việc viết thêm Negative Lookahead kèm với dấu chấm dạng Link demo: https://regex101.com/r/SThqo2/2 Bắt 1 chuỗi bất kỳ nằm ở nhiều dòng (mutiline)Biểu thức RegEx: Sẽ bắt được cả toàn bộ chuỗi nhiều dòng sau đây:
Giải thích tại sao lại bắt được. Rất đơn giản, là vì Bình thường nếu tìm một chuỗi dài liên tiếp, không quan tâm là ký tự hay chữ số, ta hay viết là Các bạn có thể xem link demo: https://regex101.com/r/irhKCk/1 Sử dụng RegEx trong thực tếTrong thực tế RegEx có thể được gõ trực tiếp ở bất kỳ trình Editor nào. Ví dụ mình hay dùng Notepad++, hoặc Visual Studio Thêm thật nhiều ví dụ cho bạn tham khảo (để xem sức mạnh của RegEx)Check một chuỗi ngày tháng bất kỳ có hợp lệ hay không tính theo năm nhuậnBiểu thức RegEx:
Sẽ đúng cho:
Và sẽ không trùng với:
Check 1 chuỗi ngày tháng phải có cả ngày và giờBiểu thức RegEx:
Sẽ đúng cho:
Và sẽ không trùng với:
Check 1 chuỗi bất kỳ xem có phải ngày hoặc giờ hay khôngBiểu thức RegEx:
Sẽ đúng cho:
Và sẽ không trùng với:
Tóm lại:
Tham khảoTham khảo thêm toàn bộ cú pháp RegEx bằng tiếng Anh tại: https://www.cheatography.com/davechild/cheat-sheets/regular-expressions/
Bài tập về nhàBạn ngứa tay muốn thử học RegEx ngay và luôn cho nóng. Vậy hãy thử thực hành bằng một số bài tập từ dễ đến khó sau đây nhé. Bài tập nhập môn:
Bài tập dành cho học sinh giỏi (lớp học thêm)
Nếu các bài tập trên đây vẫn chưa đủ, các bạn hãy làm thêm các bài tập tại trang https://regexone.com nhé, rất nhiều ví dụ hay. Kết bàiHi vọng bài viết nhỏ này đã giúp bạn học được cú pháp viết RegEx và áp dụng vào công việc thường ngày. Mình dùng Regex rất nhiều và nó là trợ thủ đắc lực trong quá trình code. Các bạn thì sao? bạn đã dùng Regex vào những việc gì? Hãy kể tên bên dưới comment để mình cùng học hỏi với nhé. Thanks các bạn đã đọc, hãy comment, upvote và share bạn bè thật nhiều nhé! Update v2.2: Thêm các bài tập để các bạn luyện thêm (theo yêu cầu của nhiều bạn, nhớ tự làm trước khi dòm đáp án nhé ^^!)BTU1. Tìm ra các chuỗi là số điện thoại trong chuỗi sau. Chú ý một số loại ra một số chuỗi không phải là số điện thoại
Lời giải https://regexr.com/38pvb BTU2. Tìm ra chuỗi là địa chỉ email trong chuỗi sau, chú ý loại bỏ các chuỗi k phải địa chỉ emai thực sự.
Lời giải: https://regexr.com/3bcrb BTU3. Tìm cách lấy ra và ngăn cách chuỗi số sau thành có phần trăm phần nghìn.
Lời giải: regexr.com/4409r BTU4. Lấy ra các chuỗi ngăn cách bởi dấu phẩy theo định dạng của một file CSV như sau (chú ý là chuỗi bị xuống dòng):
Lời giải: https://regexr.com/3apuc BTU5. Tìm và xóa đi toàn bộ các thẻ HTML trong đoạn text dưới đây:
Lời giải: https://regexr.com/3cak1 BTU6. Tìm cách loại bỏ các chuỗi console.log() do lập trình viên viết để test ra khỏi code trước khi bàn giao
Lời giải: https://regexr.com/3fi66 BTU7. Loại bỏ toàn bộ các đoạn comment code trong đoạn code sau đây:
Lời giải: https://regexr.com/3aeb7 BTU8. Lấy ra các chuỗi là các URL đầy đủ trong đoạn text dưới đây:
Lời giải: https://regexr.com/39nr7 BTU9. Lấy ra toàn bộ các URL của một video Youtube từ đoạn text test sau đây
Lời giải: https://regexr.com/3akf5 BTU10. Lấy ra các đoạn text là giá trị màu RBG
Lời giải: https://regexr.com/38lmo |