Phạm vi ngoặc vuông trong biểu thức chính quy Regexp
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 đấ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 và /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
Các bài viết liên quan
Định lượng hỏi trong biểu thức chính quy Regexp
Định lượng hỏi ? là một ký tự đặc biệt trong Regexp và nó có ý nghĩa là gì ?RegularĐịnh lượng cộng trong biểu thức chính quy Regexp
Định lượng + là một ký tự đặc biệt trong Regexp mà bắt buộc chúng ta phải nhớ.RegularBiểu thức chính quy Regular trong javascript
Đối tượng Regexp cung cấp các phương pháp mạnh mẽ để tìm kiếm và thay thế văn bản trong jsvascriptRegularLớp ký tự đặc biệt trong chuỗi string và regexp
Để làm việc với chuỗi string và regexp một cách hoàn hảo và mạnh mẽ. Các bạn bắt buộc phải hiểu về nó.RegularĐịnh lượng lười biến trong biểu thức chính quy Regexp
Định lượng lười biến *? +? ?? {0,1}? {0,}? {1,}? {x,y}? rất mạnh mẽ. Tuy chỉnh hành vi tham lam.Regular