Hạn chế sự tham lam trong biểu thức chính quy trong Python
Biểu thức chính quy mặc định là tham lam. Điều này có nghĩa là chúng chiếm giữ số lượng ký tự tối đa có thể. Hãy cùng phân tích một ví dụ. Giả sử chúng ta có một chuỗi như sau:
txt = 'aeeex zzz x kkk'
Trong chuỗi này, chúng ta muốn tìm chuỗi con
'aeeex' theo mẫu sau:
chữ cái 'a', sau đó là bất kỳ ký tự nào
một lần hoặc nhiều lần, sau đó là chữ cái 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Mặc dù chúng ta muốn nhận được chuỗi '! zzz
x kkk', nhưng kết quả in ra sẽ là chuỗi '! kkk'.
Vấn đề nằm ở chỗ biểu thức chính quy của chúng ta tìm kiếm
tất cả các ký tự từ chữ cái 'a' đến chữ cái
'x'. Nhưng trong chuỗi của chúng ta có hai chữ cái
'x'! Do tính tham lam, kết quả là
biểu thức chính quy tìm kiếm cho đến chữ 'x' cuối cùng,
từ đó chiếm giữ không phải thứ chúng ta
cần.
Tất nhiên, thường thì hành vi như vậy chính là thứ chúng ta cần. Nhưng cụ thể trong trường hợp này, chúng ta cần hủy bỏ tính tham lam và yêu cầu biểu thức chính quy tìm kiếm cho đến chữ 'x' đầu tiên. Trong trường hợp này nên đặt dấu hỏi sau toán tử lặp:
res = re.sub('a.+?x', '!', txt)
print(res) # sẽ in ra chuỗi '! zzz x kkk'
Có thể hạn chế tính tham lam cho tất cả các toán tử
lặp: cả *, ?, và
{} - như thế này: *?, ??
và {}?.
Cho một chuỗi:
txt = 'aba accca azzza wwwwa'
Viết biểu thức chính quy tìm tất cả
các chuỗi có chữ cái
'a' ở hai đầu, và thay thế mỗi chuỗi đó bằng
'!'. Giữa các chữ cái 'a' có thể
là bất kỳ ký tự nào (ngoại trừ 'a').