Lọ mọ viết cái mã chuẩn hóa ngày tháng năm đến khổ, hóa ra dùng một dòng Regular Expression là xong!

Vào đề luôn anh chị em ạ, nó là cái dòng này:

\b(0?[1-9]|[12]\d|3[01])[\/\-.](0?[1-9]|[12]\d|3[01])[\/\-.](\d{2}|\d{4})\b

Xử lý tuốt chỉ nhờ một dòng trên mà thôi, nó sẽ bắt đủ các dạng ngày tháng năm thường dùng:

  • 2 ký tự đầu bắt buộc là số, 2 ký tự tiếp cũng bắt buộc là số, các ký tự năm có thể là 2 số hoặc 4 số;
  • không cho phép chữ cái, ký tự đặc biết trong chuỗi. Chỉ có số mà thôi;
  • ngày, tháng năm có thể được phân cách bằng / hoặc – hoặc dấu .
  • 2 ký tự đầu có thể là ngày hoặc tháng, 2 ký tự tiếp theo có thể là tháng hoặc ngày để khớp được với cả hai kiểu dd/mm và mm/dd
  • các giá trị số chỉ ngày chỉ được phép nằm trong khoảng từ 0 cho đến 31;

Quay lại nhìn đống mã PHP xử lý thủ công ngày tháng năm ở bài này mà phát sợ!

Biểu thức chính quy trên sẽ giúp ta bắt được các ngày tháng năm kiểu như dưới đây:

  • 12-02-2015
  • 5-6-2017
  • 3/05/2018
  • 12/24/2019
  • 1.1.2018
  • 7-9-18
  • 1.31.2018

Và bỏ qua các dữ liệu kiểu này:

  • 12s3/2/123
  • 13/a/3346
  • 32/05/2018
  • 11/08/203
  • 52/53/2018

Đấy, các bạn thấy sức mạnh của RegExp chưa?

Đối với giá trị năm mà chúng ta biết trước khoảng giá trị hợp lệ thì bạn thậm chí còn có thể cải tiến đoạn mã trên. Ví dụ nếu đó là năm của người sống, thì giá trị đó không thể nhỏ hơn 1900, và tất nhiên không thể lớn hơn 2100. Trường hợp vậy chúng ta có thể chỉnh mã trên thành như sau:

\b(0?[1-9]|[12]\d|3[01])[\/\-.](0?[1-9]|[12]\d|3[01])[\/\-.](\d{2}|19\d{2}|20\d{2})\b

Khi đó các dữ liệu như:

  • 1.31.1899
  • 12/05/2100
  • 02-05-1000

Sẽ bị bỏ qua, vì các năm này nằm ngoài khoảng giá trị cho phép.

Trường hợp bạn biết cụ thể hơn nữa, chẳng hạn năm chỉ nằm trong khoảng từ 2005 đến 2015 mới hợp lệ, thì câu lệnh sẽ thành thế này:

\b(0?[1-9]|[12]\d|3[01])[\/\-.](0?[1-9]|[12]\d|3[01])[\/\-.](\d{2}|200[5-9]|201[0-5])\b

Nói chung RegExp mới đầu nhìn rất là quái dị, nhưng bạn cứ tập dần rồi sẽ quen. Một bài viết hay về chủ để này do tác giả Chung Minh Tú viết và bạn rất nên dùng website regex101.com để thực hành, vì nó rất trực quan, gõ lệnh thấy kết quả ngay, học tiến bộ nhanh lắm.

Ngoài bài của bạn CMT, bạn có thể tham khảo bài tôi mới viết về các cú pháp cơ bản của RegEx.