Lookahead và Lookbehind (Tích cực và Tiêu cực) trong Biểu thức chính quy Python
Đôi khi cần giải quyết bài toán dạng này:
tìm chuỗi 'aaa' và thay thế nó
bằng '!', nhưng chỉ khi phía sau
'aaa' là '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 bài toán 'một cách trực tiếp',
thì sẽ không thành công:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # sẽ in ra '! baaa', trong khi muốn '!x baaa'
Lookahead (Xem trước)
Để giải quyết bài toán, 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 các dấu ngoặc đặc biệt (?= ),
chỉ kiểm tra điều kiện nhưng không "chiếm" nó.
Các dấu ngoặc này được gọi là positive lookahead (xem trước tích cực). Tích cực - vì 'x'
(trong trường hợp của chúng ta) phải tồn tại - chỉ khi đó
việc thay thế mới xảy ra.
Hãy áp dụng các dấu ngoặc này để giải quyết bài toán của chúng ta:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # sẽ in ra '!x aaab
Cũng có negative lookahead (xem trước tiêu cực)
- (?! ) - ngược lại, nó nói rằng
thứ gì đó phải không tồn tại. Trong ví dụ tiếp theo,
thay thế sẽ xảy ra, chỉ khi
sau 'aaa' KHÔNG phải là 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # sẽ in ra 'aaax !b'
Lookbehind (Xem phía sau)
Tương tự, có positive lookbehind (xem phía sau tích cực)
- (?<= ). Trong
ví dụ tiếp theo, thay thế sẽ xảy ra, chỉ
khi trước 'aaa' là 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # sẽ in ra 'x!'
Và cũng có negative lookbehind (xem phía sau tiêu cực)
- (?<! ). Trong ví dụ tiếp theo,
thay thế sẽ xảy ra, chỉ khi trước
'aaa' không phải là 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # sẽ in ra 'b!'
Bài tập thực hành
Cho một chuỗi chứa tên các hàm:
txt = 'func1() func2() func3()'
Hãy lấy mảng các tên hàm từ chuỗi.
Cho một chuỗi với một thẻ:
txt = '<a href="" class="eee" id="zzz">'
Hãy lấy mảng tên các thuộc tính của thẻ này.
Cho một chuỗi với các biến:
txt = '$aaa $bbb $ccc xxxx'
Hãy lấy các chuỗi con mà phía trước nó là ký tự đô la.