Positive và Negative Lookahead trong Biểu thức chính quy JavaScript
Đôi khi bạn cần giải quyết một nhiệm vụ kiểu như: tìm
chuỗi 'aaa' và thay thế nó bằng '!',
nhưng chỉ khi sau 'aaa' có
'x', còn bản thân 'x' thì
không thay thế. Nếu chúng ta cố gắng giải quyết nhiệm vụ
'trực diện', chúng ta sẽ không thành công:
'aaax baaa'.replace(/aaax/g, '!'); // trả về '! baaa', trong khi muốn '!x baaa'
Lookahead
Để giải quyết nhiệm vụ, cần một cách để nói rằng
'x' không nên bị thay thế. Điều này được thực hiện
bằng cách sử dụng dấu ngoặc đặc biệt (?= ),
chỉ nhìn mà không lấy đi theo.
Những dấu ngoặc này được gọi là positive lookahead
. Positive - vì 'x'
(trong trường hợp của chúng ta) phải có - chỉ khi đó
việc thay thế mới xảy ra.
Hãy áp dụng những dấu ngoặc này để giải quyết nhiệm vụ của chúng ta:
'aaax aaab'.replace(/aaa(?=x)/g, '!'); // trả về '!x aaab'
Cũng có negative lookahead
- (?! ) - nó ngược lại, nói rằng
cái gì đó phải không có. Trong ví dụ tiếp theo,
thay thế sẽ xảy ra, chỉ khi sau 'aaa'
KHÔNG phải là 'x':
'aaax aaab'.replace(/aaa(?!x)/g, '!'); // trả về 'aaax !b'
Lookbehind
Tương tự, có positive lookbehind
- (?<= ). Trong ví dụ tiếp theo
thay thế sẽ xảy ra, chỉ khi trước
'aaa' có 'x':
'xaaa'.replace(/(?<=x)aaa/g, '!'); // trả về 'x!'
Và cũng có negative lookbehind
- (?<! ). Trong ví dụ tiếp theo, thay thế
sẽ xảy ra, chỉ khi trước 'aaa'
không có 'x':
'baaa'.replace(/(?<!x)aaa/g, '!'); // trả về 'b!'
Bài tập thực hành
Cho một chuỗi chứa tên hàm:
let str = 'func1() func2() func3()';
Lấy một mảng tên hàm từ chuỗi.
Cho một chuỗi với thẻ:
let str = '<a href="" class="eee" id="zzz">';
Lấy một mảng tên thuộc tính của thẻ này.
Cho một chuỗi với các biến:
let str = '$aaa $bbb $ccc xxxx';
Lấy các chuỗi con, mà đằng trước chúng có ký tự đô la.