Nhìn sau tiêu cực trong biểu thức chính quy Regular
Chào các bạn
Trong bài viết này mình sẽ nói nhìn sau tiêu cực (?<!y)x trong biểu thức chính quy Regular
Nhìn sau tiêu cực
Nhìn sau tiêu cực (?<!y)x thì cũng như nhìn sau (?=y)x thôi. Nhưng bây giờ ý nghĩa nó khác.
Tốt nhất là trong các bài hướng dẫn về Regexp này thì nên đơn giản càng tốt. Nếu phức tạp quá thì rất khó giải thích. Nếu các bạn mới học thì tốt nhất là cuộn xuống dưới và xem bài viết của mình từ dưới lên.
Mọi thứ phức tạp đều đi từ cái đơn giản
Ok. bây giờ chúng ta nên đi vào ví dụ nào
- Trận đấu /(?<!Hồ)Quang/
1let str = "Hồ Quang Trí"; 2 3let reg = /(?<!Hồ)Quang/ 4 5let ketQua = reg.exec(str); 6 7console.log(ketQua); // ['Quang', index: 3, input: 'Hồ Quang Trí', groups: undefined]
Ý nghĩa của trận đấu /(?<!Hồ)Quang/ là. Bắt đầu bằng Quang rồi nhìn sau hỏi xem có khác Hồ hay không. Vì ở đây trận đấu này không có cờ hay định lượng hay nhóm hay bất cứ điều gì nên cũng dể giải thích.
Cái mình cần bạn chú ý là ký tự khoảng trắng \s ở trên. Vì khoảng trắng khó nhìn thấy nên mình dùng lớp ký tự đặt biệt \s để bạn dể nhìn cũng như mình dể nói nhé.
1/** 2 * Hồ\sQuang Trí 3 * HồQuang 4 */
Bây giờ nó sẻ so sánh như thế này. Nó lấy ồ\s so với Hồ. Như bạn thấy nó khác nhau đúng không ạ. Trong chuỗi một ký tự cũng rất quan trọng. Nên sai sót là điều không thể nào tránh được đâu.
Bây giờ chúng ta cùng nhau đi tiếp một ví dụ khác. Ví dụ này cũng phức tạp hơn.
- Trận đấu /.+?(?<!(Hồ|\s))Quang/
1let str = "Hồ Quang Trí"; 2 3let reg = /.+?(?<!(Hồ|\s))Quang/ 4 5let ketQua = reg.exec(str); 6 7console.log(ketQua); // null
Trận đấu trên có ý nghĩa là. Bắt đầu bằng dấu chấm .. Dấu chấm . đại diện cho bất kỳ ký tự nào ngoài \n theo sau nó là định lượng tham lam + tiếp theo là định lượng hỏi ?. Hỏi ? mà sau định lượng tham lam là thành ra lười biến +?. Mỗi lần chạy nó xem phía sau có phải là Quang hay không. Nếu đúng thì nhìn sau tiêu cực hỏi có phải là Hồ hoặc \s hay không. Nếu không phải thì nó trả về kết quả. Ở ví dụ trên là phải nên nó chạy tiếp và chuỗi nguồn str chúng ta không khớp với trận đấu nên null được trả lại.
Nếu chúng ta thay \s thành \S thì bây giờ kết quả lại khác.
1let str = "Hồ Quang Trí"; 2 3let reg = /.+?(?<!(Hồ|\S))Quang/ 4 5let ketQua = reg.exec(str); 6 7console.log(ketQua); // ['Hồ Quang', undefined, index: 0, input: 'Hồ Quang Trí', groups: undefined]
Các bạn để ý kỹ đầu ra kết quả chúng ta ngay vị trí 1 là nhóm (Hồ|\S) chúng ta là undefined nhé. Vì nếu đó mà có kết quả thì null rồi đâu nữa.
Trận đấu của chúng ta vậy là cũng khó rồi đó. Càng dài nữa thì càng phức tạp nữa. Cho nên tùy bài toán mà các bạn áp dụng.
Mình chỉ hướng dẫn từng cái cơ bản thôi. Nhiệm vụ của các bạn là sử dụng nó và ghép nó lại thành những thứ phức tạp hơn nếu bài toán yêu cầu khó.
Nếu bạn muốn lấy nhiều kết quả hơn thì cứ thêm cờ g cho trận đấu. Ở ví dụ dưới đây mình có sửa chuỗi nguồn lại tí.
- Trận đấu /.+?(?<!(Hồ|\S))Quang/g
1let str = "Hồ Quang Trí Hồ Quang Trí"; 2 3let reg = /.+?(?<!(Hồ|\S))Quang/g; 4 5while (true) { 6 let ketQua = reg.exec(str); 7 if (!ketQua) { 8 break; 9 } 10 console.log(ketQua); 11 12 // ['Hồ Quang', undefined, index: 0, input: 'Hồ Quang Trí Hồ Quang Trí', groups: undefined] 13 // [' Trí Hồ Quang', undefined, index: 8, input: 'Hồ Quang Trí Hồ Quang Trí', groups: undefined] 14}
hoặc dùng phương pháp khác.
1let str = "Hồ Quang Trí Hồ Quang Trí"; 2 3let reg = /.+?(?<!(Hồ|\S))Quang/g; 4 5let iterable = str.matchAll(reg); 6 7while (true) { 8 let { done, value } = iterable.next(); 9 if (done) { 10 break; 11 } 12 console.log(value); 13 14 // ['Hồ Quang', undefined, index: 0, input: 'Hồ Quang Trí Hồ Quang Trí', groups: undefined] 15 // [' Trí Hồ Quang', undefined, index: 8, input: 'Hồ Quang Trí Hồ Quang Trí', groups: undefined] 16}
Nếu bạn chỉ muốn lấy ra mảng kết quả mà không bao gồm những thứ như trên thì dùng phương pháp match()
1let str = "Hồ Quang Trí Hồ Quang Trí"; 2 3let reg = /.+?(?<!(Hồ|\S))Quang/g; 4 5let ketQua = str.match(reg); 6 7console.log(ketQua); // ['Hồ Quang', ' Trí Hồ Quang']
Tổng kết
Trong bài viết này mình đã nói về nhìn sau tiêu cực (?<!y)x trong biểu thức chính quy regexp.
Nhiệm vụ của các bạn chỉ cần nhớ ý nghĩa và cú pháp của nó thôi. Cái này chắc phải cần thời gian. Không vội được đâu. Nên các bạn thấy khó hiểu quá thì cũng đừng bi quan nhé. Từ từ sẻ hiểu.
Ok hẹn gặp lại bạn ở bài viết sau nhé.
- object
- regular
- nhìn trước
- nhìn sau
- boolean
- string
Các bài viết liên quan
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.RegularNhóm nội dung trong biểu thức chính quy Regexp
Nhóm () cũng là một ký tự đặc biệt trong Regular. Nó có rất nhiều thứ mà các bạn cần phải biết.RegularLoại trừ bộ nhớ khỏi nhóm trong biểu thức chính quy Regular
Để loại trừ bộ nhớ khỏi nhóm thì chúng ta dùng (?:). Đi kèm với đó thì mất đi cơ hội.Regular