🦁 Regexp 🦁

Phạm vi ngoặc vuông trong biểu thức chính quy Regexp

Phạm vi [] trong regexp rất quan trọng. Nó có rất rất là nhiều ý nghĩa.
js_masterRegular
Regular-Expression-trong-JavaScript.jpg

Chào các bạn

Trong bài viết viết này mình sẽ nói về phạm vi ngoặc vuông []. Cũng là một ký tự đặc biệt trong đối tượng Regexp

Phạm vi

Phạm vi ngoặc vuông [] này cũng rất quan trọng trong regexp. Một thứ mà bắt buộc bạn phải biết. Nói chung làm việc với Regexp này có rất rất là nhiều ký tự đặc biệt mà bắt buộc phải nhớ.

Để có thể đẳng cấp. Thì nhiệm cụ của các bạn chỉ cần nhớ ý nghĩa của nó thôi.

Cú pháp

1let str = "0123 456 153 789";
2
3let reg = /1[25]3/;
Trận đấuMô tả
/[]/Phạm vi ngoặc vuông [] sẻ khớp với bất kỳ 1 ký tự nào trong dấu ngoặc vuông đó. Nó có ý nghĩa cũng tương đương dấu hoặc | và cũng có những khác biệt khác nữa.

Trận đấu /1[25]3/ có ý nghĩa là. Bắt đầu bằng số 1 tiếp theo là số 2 hoặc số 5 tiếp theo là số 3.

  • Khớp với 123 153.

Không có cờ g

  • Trận đấu /1[25]3/
1let str = "0123 456 153 789";
2
3let reg = /1[25]3/;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['123', index: 1, input: '0123 456 153 789', groups: undefined]

Chúng ta cũng có thể viết trận đấu /1[25]3/ thành /1(2|5)3/. Nhưng vì mình chưa nói đến nhóm () nên các bạn chỉ cần xem ví dụ thôi nhé. Đến bài nhóm mình sẻ giải thích.

  • Trận đấu /1(2|5)3/
1let str = "0123 456 153 789";
2
3let reg = /1(2|5)3/;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['123', '2', index: 1, input: '0123 456 153 789', groups: undefined]

Đầu ra 2 trận đấu tuy khác nhau. Nhưng không đáng lo ngại. Cái chúng ta quan tâm là kết quả của trận đấu chúng ta đả ra đúng.

Có cờ g

  • Trận đấu /1[25]3/g
1let str = "0123 456 153 789";
2
3let reg = /1[25]3/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['123', '153']

Khi có cờ g thì hành vi của chức năng match() thay đổi. Ở các bài trước mình cũng đã nói rồi. Nhưng tốt nhất là cứ nên nói lại. Đôi lúc các bạn ko biết.

  • Trận đấu /1(2|5)3/g
1let str = "0123 456 153 789";
2
3let reg = /1(2|5)3/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['123', '153']

Khi có cờ g thì trận đấu /1(2|5)3/g/1[25]3/g có kết quả giống nhau. Chúng ta cũng nên đi vào bài viết về phạm vi dấu ngoặc vuông [] thì hay hơn. Vì nó còn nhiều thứ khác nữa phải nói lắm.

Đơn nhiên các bạn có thể truyền bất kỳ ký tự nào vào trong phạm vi dấu ngoặc vuông [@#\d12\]sc...].

Khi bạn muốn tìm ký tự dấu ngoặc vuông thì các bạn bắt buộc phải thoát khỏi nó /1[\[\]3]/.

  • Trận đấu /1[\[\]3]5/.
1let str = "0123 456 1[5 789";
2
3let reg = /1[\[\]3]5/;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1[5', index: 9, input: '0123 456 1[5 789', groups: undefined]

Ý nghĩa của trận đấu này là. Bắt đầu bằng số 1 tiếp theo là dấu ngoặc vuông mở [ hoặc dấu ngoặc vuông đóng ] hoặc số 3 tiếp theo là số 5.

  • Khớp với: 1[5 1]5 135

Đổi lại ví dụ cho nó ra khớp kết quả cho các bạn nhìn.

  • Trận đấu /1[\[\]3]5/g
1let str = "0123 91]50 456 1[5 789 t135i";
2
3let reg = /1[\[\]3]5/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1]5', '1[5', '135']

Ở ví dụ trên mình có thêm cờ g để cho các bạn dể hình dung. Vì đầu ra bây giờ chỉ có mảng kết quả các trận đấu.

Chúng ta cũng có thể thêm bất kỳ lớp ký tự đặc biệt nào cũng như ký tự đặc biệt nào mà không cần phải thoát nó.

  • Trận đấu /1[\[\d\]3()|\w]5/g
1let str = "0123 91]50 456 1[5 789 t135i 125 1|5 1_5 1(5 1)5";
2
3let reg = /1[\[\d\]3()|\w]5/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1]5', '1[5', '135', '125', '1|5', '1_5', '1(5', '1)5']

Hoặc chúng ta cũng có thể thoát khỏi nó bằng cách thêm dấu \ trước các ký tự đặt biệt trong dấu ngoặc vuông [] mà không sao cả. Đơn nhiên đi cùng với đó thì trận đấu chúng ta nhìn phức tạp hơn mà không cần thiết.

  • Trận đấu /1[\[\d\]3\(\)\|\w]5/g
1let str = "0123 91]50 456 1[5 789 t135i 125 1|5 1_5 1(5 1)5";
2
3let reg = /1[\[\d\]3\(\)\|\w]5/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1]5', '1[5', '135', '125', '1|5', '1_5', '1(5', '1)5']

Ở ví dụ trên mình đã thoát các ký tự đặc biệt là: \[ \] \( \) \|. Đơn nhiên là còn nhiều ký tự đặc biệt khác nữa.

Thế bây giờ chúng ta thử thoát lớp ký tự đặc biệt thì xem điều gì sẽ xãy ra nhé. Nếu các bạn chưa biết lớp ký tự đặt biệt thì xem thêm tại đây regexp

Trước khi đi vào ví dụ thì mình sẽ xóa bớt các ký tự đặc biệt trong dấu ngoặc vuông mà mình đã thoát ở ví dụ trước đi. Cho dể nhìn và giải thích.

  • Trận đấu /1[\\d\\w]5/g
1let str = "0123 91]50 105 10 456 1[5 789 t135i 125 1|5 1_5 1(5 1)5";
2
3let reg = /1[\\d\\w]5/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // null

Kết quả của trận đấu chúng ta là null. Vậy tại sao ?. Rất đơn giản. Lý do là khi chúng ta thoát \\d với \\w thì ý nghĩa nó khác.

  • Khi chưa thoát /1[\d\w]5/g

    • Bắt đầu bằng số 1 tiếp theo là một số \d hoặc một số, ký tự, dấu gạch dưới \w tiếp theo là số 5
    • Khớp với: 105 đến 195 1a5 đến 1z9 1_5

      1let str = "105 195 1a5 1z5 1_5 125";
      2
      3let reg = /1[\d\w]5/g;
      4
      5let ketQua = str.match(reg);
      6
      7console.log(ketQua); // ['105', '195', '1a5', '1z5', '1_5', '125']
  • Khi đã thoát /1[\\d\\w]5/g

    • Bắt đầu bằng số 1 tiếp theo là dấu \ hoặc d hoặc w tiếp theo là số 5
    • Khớp với: 1\5 1d5 1w5

      1let str = "105 195 1a5 1z5 1_5 125 1\\5 1d5 1w5";
      2
      3let reg = /1[\\d\\w]5/g;
      4
      5let ketQua = str.match(reg);
      6
      7console.log(ketQua); // ['1\\5', '1d5', '1w5']
    • Các bạn lưu ý. Vì trong chuỗi dấu \ cũng là ký tự đặt biệt. Nên khi bạn muốn \ xuất hiện trong chuỗi thì các bạn bắt buộc phải thoát khỏi nó \\

      1let thoat = "105 195 1a5 1z5 1_5 125 1\\5 1d5 1w5"; // Khi thoát
      2let khongThoat = "105 195 1a5 1z5 1_5 125 1\5 1d5 1w5"; // Khi không thoát
      3
      4console.log(thoat);      // 105 195 1a5 1z5 1_5 125 1\5 1d5 1w5
      5console.log(khongThoat); // 105 195 1a5 1z5 1_5 125 1 1d5 1w5

Không chỉ như vậy. Mà phạm vi dấu ngoặc vuông [] còn làm được nhiều thứ khác nữa. Ví dụ như xác định phạm vi từ /[0-9]/ hoặc /[a-z]/ hoặc /[0-9a-z]/ chẳng hạn. Và nhiều thứ khác nữa.

  • Trận đấu /1[0-9]1/g
1let str = "123 121 101 1906 191"
2
3let reg = /1[0-9]1/g
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['121', '101', '191']

Trận đấu /1[0-9]1/g có ý nghĩa là. Bắt đầu bằng số 1 tiếp theo là số từ 0 đến 9 tiếp theo là số 1

Khớp với: 101 đến 109

  • Trận đấu /1[a-z]1/g
1let str = "123 121 101 1906 191 1a1 1A1 1z1"
2
3let reg = /1[a-z]1/g
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1a1', '1z1']

Như các bạn thấy. Không có 1A1 trong mảng kết quả nhé. Vì nó tìm kiếm phân biệt HOA hoặc thường. Để lấy được 1A1 thì các bạn sửa đổi trận đấu lại thành /1[a-zA-Z]1/g hoặc /1[a-z]1/gi hoặc /1[A-Z]1/gi. Cờ gi hoặc ig trước hay sau thì cũng không quan trọng nhé các bạn.

1let str = "123 121 101 1906 191 1a1 1A1 1z1"
2
3let reg = /1[a-z]1/gi;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1a1', '1A1', '1z1']

Ở ví dụ trên mình thêm cờ i vào. Bây giờ thì kết quả đã bao gồm 1A1. Cũng từ các ví dụ trên. Chúng ta kết hợp lại /1[a-z0-9]1/ig

  • Trận đấu /1[a-z0-9]1/ig
1let str = "123 121 101 1906 191 1a1 1A1 1z1"
2
3let reg = /1[a-z0-9]1/ig;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['121', '101', '191', '1a1', '1A1', '1z1']

Không chỉ có vậy. Chúng ta có thể kết hợp với tất cả các thứ khác. Ví dụ ở đây mình thêm định lượng tham lam cộng +.

  • Trận đấu /1[a-z0-9]+1/ig
1let str = "123 121 101 1906 102941 191 1a1 1A1 1z1"
2
3let reg = /1[a-z0-9]+1/ig;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['121', '101', '102941', '191', '1a1', '1A1', '1z1']

Ở các bài trước mình đả có giải thích về định lượng +. Nếu bạn không biết bạn có thể xem thêm về nó tại đây định lượng +

Chúng ta cũng có thể thêm chế độ lười biến cho nó bằng cách thêm ? ở sau định lượng tham lam. Ví dụ ở đây là cộng +

  • Trận đấu /1[a-z0-9]+?1/ig
1let str = "123 121 101 190610321 102941 191 1a1 1A1 1z1"
2
3let reg = /1[a-z0-9]+?1/ig;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['121', '101', '19061', '102941', '191', '1a1', '1A1', '1z1']

Cái mình cần các bạn chú ý đến đây là số 190610321. Khi có ? thì kết quả là '19061'. Khi không có ? thì kết quả sẻ khác.

  • Trận đấu /1[a-z0-9]+1/ig
1let str = "123 121 101 190610321 102941 191 1a1 1A1 1z1"
2
3let reg = /1[a-z0-9]+1/ig;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['121', '101', '190610321', '102941', '191', '1a1', '1A1', '1z1']

Khi không có hỏi thì kết quả là '190610321'. Các bạn xem đầu ra 2 trận đấu ở trên là thấy.

Loại trừ trong ngoặc [^]

Để loại trừ một ký tự hoặc nhiều ký tự trong phạm vi dấu ngoặc vuông [] thì chúng ta chỉ cần thêm ký tự dấu mũ ^

  • Trận đấu /1[^0-9]2/g
1let str = "123 121 102 191 1a2 1A2 1z2"
2
3let reg = /1[^0-9]2/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1a2', '1A2', '1z2']

Trong ví dụ trên. Ý nghĩa của trận đấu /1[^0-9]2/g này là. Bắt đầu bằng số 1 tiếp theo loại trừ tất cả số 0 đến 9 tiếp theo là số 2.

Không khớp: 102 đến 192.

Cũng từ đó nếu muốn loại trừ nhiều thì chúng ta chỉ cần nhóm () nó lại thôi. Nhưng vì mình chưa nói về nhóm () nên các bạn cứ xem qua ví dụ trước nhé.

  • Trận đấu /1([^0-9])+2/g
1let str = "123 121 102 191 1a2 1Axesr2 1z2 1e535e2"
2
3let reg = /1([^0-9])+2/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['1a2', '1Axesr2', '1z2']

Cuối cùng cái mình cần các bạn lưu ý là. Bình thường dấu ^ dùng để loại trừ trong phạm vi dấu ngoặc vuông [^...] và dấu - dùng dể xác khoảng nào đó [a-z]. Vậy chúng ta muốn tìm kiếm nó thì như thế nào.

Rất đơn giản, các bạn chỉ cần cho nó ở cuối dấu ngoặc vuông thôi [...^-] vậy là nó không còn ý nghĩa gì nữa. Bây giờ nó đơn giản chỉ là ký tự ^ với - thôi.

  • Trận đấu /[-^]/g
1let str = "Hồ-Quang^Trí"
2
3let reg = /[-^]/g;
4
5let ketQua = str.match(reg);
6
7console.log(ketQua); // ['-', '^']

Và còn nhiều nữa. Rồi từ từ mình sẽ viết mình giải thích cho các bạn hiểu. Học cái này không thể vội vàng được.

Tổng kết

Trong bài viết này mình đã nói về phạm vi ngoặc vuông [] và ý nghĩa của nó. Nếu bạn chưa biết thì xem lại từ đầu nhé. Chậm mà chắc.

  • phạm vi
  • regexp
  • biểu thức
  • string
  • regular

OFFJS.COM - Blog học tập giải trí - 🐲

Chia sẻ nhiều kiến thức thú vị trong lập trình cũng như cuộc sống.

Giới thiệu


Trang web này mình sẽ nói về kiến thức lập trình và cuộc sống mà các bạn mới học hay đang dự định học. Có một bước đi đầu đời vững chắc.

Hồ Quang Trí.jpg

Đi kèm với đó là những lý thuyết và các dòng code minh họa. Để các bạn dễ hình dung.

Đơn nhiên cũng không dễ dàng ngày một ngày hai mà học hết được.

Học Tập Là Một Con Đường Dài Vô Tận

Nó sẽ nuốt các bạn vô số thời gian nhưng bù lại khi đã biết thì mọi thứ thật là tuyệt.

1console.log("Hồ Quang Trí");

Nếu có ai nói bạn học lập trình trong vòng 3 đến 6 tháng thì mình xin nói thật không bao giờ có chuyện đó nhé.

Chúc các bạn thành công.

Chân trang

phone-toan-phat.png

0353210168

address-toan-phat.png

Việt Nam