Trăn regex tham lam

Sẵn sàng để kiếm được đai đen của siêu năng lực biểu thức chính quy của bạn?

Bạn cũng có thể xem video giải thích mà tôi đã tạo cho bài viết này

Python Regex Tham lam so với Định lượng không tham lam

Trăn regex tham lam

Xem video này trên YouTube


Nếu bạn là người bận rộn, đây là phiên bản ngắn của hướng dẫn này

Định nghĩa lượng tử tham lam

Một bộ định lượng tham lam như

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
2 khớp với càng nhiều ký tự càng tốt (trận đấu dài nhất). Ví dụ: regex
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3 sẽ khớp với càng nhiều
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt trong chuỗi
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5 của bạn—mặc dù các chuỗi con
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
7,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
8 đều khớp với regex
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3

Định nghĩa lượng tử không tham lam

Một bộ định lượng không tham lam, chẳng hạn như

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
00,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
02 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
03 khớp với càng ít ký tự càng tốt (khớp ngắn nhất có thể). Ví dụ: regex
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
04 sẽ khớp với càng ít
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt trong chuỗi của bạn
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5. Như vậy là khớp với ký tự đầu tiên
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 là xong


Các kỹ sư của Google, Facebook và Amazon là những bậc thầy về biểu thức chính quy. Nếu bạn cũng muốn trở thành một người như vậy, hãy xem cuốn sách mới của chúng tôi. Cách thông minh nhất để học Python Regex (Amazon Kindle/Print, mở trong tab mới)

Nhưng điều đầu tiên trước tiên. "định lượng" là gì? . Vì vậy, hãy đi sâu vào ba bộ định lượng regex chính của Python

Bộ định lượng Regex Python

Từ "quantifier" bắt nguồn từ tiếng Latin. ý nghĩa của nó là qantas = bao nhiêu / mức độ thường xuyên

Đây chính xác là ý nghĩa của một bộ định lượng biểu thức chính quy. bạn nói với công cụ regex tần suất bạn muốn khớp với một mẫu nhất định

bài viết liên quan. Python Regex Superpower – Hướng dẫn cơ bản

Nếu bạn nghĩ rằng bạn không xác định bất kỳ bộ định lượng nào, bạn sẽ làm điều đó một cách ngầm định. không có bộ định lượng nào có nghĩa là khớp với biểu thức chính quy chính xác một lần

Vậy các bộ định lượng regex trong Python là gì?

Định lượngÝ nghĩa
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
08Khớp biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09 không hoặc một lần
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
00Khớp biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09 không hoặc nhiều lần
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
02Khớp biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09 một hoặc nhiều lần
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
04Khớp biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09 chính xác m lần
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
06Khớp biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09 giữa m và n lần (bao gồm)

Lưu ý rằng trong hướng dẫn này, tôi cho rằng ít nhất bạn đã có một ý tưởng từ xa về biểu thức chính quy thực sự là gì. Nếu bạn chưa có, không vấn đề gì, hãy xem hướng dẫn chi tiết về regex của tôi trên blog này

Bạn có muốn làm chủ siêu năng lực regex không? . (1) nghiên cứu một chương sách, (2) giải câu đố mật mã và (3) xem video về chương giáo dục

Bạn thấy trong bảng rằng các bộ định lượng

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
2 xác định tần suất bạn lặp lại phép so khớp của biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
09

Hãy cùng xem một số ví dụ—một ví dụ cho mỗi bộ định lượng

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']

Trong mỗi dòng, bạn thử một bộ định lượng khác nhau trên cùng một văn bản

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5. Và thật thú vị, mỗi dòng dẫn đến một đầu ra khác nhau

  • Regex 0-or-one
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    05 khớp với bốn lần một
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    4. Lưu ý rằng nó không khớp với các ký tự 0 nếu nó có thể tránh làm như vậy
  • Regex zero-or-more
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    07 khớp một lần bốn
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    4 và tiêu thụ chúng. Ở cuối chuỗi, nó vẫn có thể khớp với chuỗi rỗng
  • Một hoặc nhiều regex
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    3 khớp một lần bốn
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    4. Ngược lại với bộ định lượng trước đó, nó không thể khớp với một chuỗi rỗng
  • Regex lặp lại
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    11 khớp với tối đa ba
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    4 trong một lần chạy. Nó có thể làm như vậy chỉ một lần
  • Regex lặp lại
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    13 khớp với một hoặc hai
    >>> import re
    >>> re.findall('a?', 'aaaa')
    ['a', 'a', 'a', 'a', '']
    >>> re.findall('a*', 'aaaa')
    ['aaaa', '']
    >>> re.findall('a+', 'aaaa')
    ['aaaa']
    >>> re.findall('a{3}', 'aaaa')
    ['aaa']
    >>> re.findall('a{1,2}', 'aaaa')
    ['aa', 'aa']
    4. Nó cố gắng khớp càng nhiều càng tốt

Bạn đã học các bộ định lượng cơ bản của biểu thức chính quy Python. Bây giờ, đã đến lúc khám phá ý nghĩa của thuật ngữ tham lam. Chúng ta nhé?

Trận đấu tham lam Regex Python

Khớp tham lam có nghĩa là công cụ regex (công cụ cố gắng tìm mẫu của bạn trong chuỗi) khớp với càng nhiều ký tự càng tốt

Ví dụ: regex

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3 sẽ khớp với càng nhiều
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt trong chuỗi của bạn
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5. Mặc dù các chuỗi con
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
7,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
8 đều khớp với biểu thức chính quy
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3, nhưng nó không đủ cho công cụ biểu thức chính quy. Nó luôn đói và cố gắng ăn khớp hơn nữa

Trăn regex tham lam

Nói cách khác, các bộ định lượng tham lam cung cấp cho bạn kết quả khớp dài nhất từ ​​một vị trí nhất định trong chuỗi

Hóa ra, tất cả các bộ định lượng mặc định

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
2 mà bạn đã học ở trên đều là tham lam. họ "tiêu thụ" hoặc khớp với nhiều ký tự nhất có thể để mẫu biểu thức chính quy vẫn được thỏa mãn

Dưới đây là các ví dụ trên một lần nữa, tất cả đều cho thấy công cụ regex tham lam như thế nào

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']

Trong mọi trường hợp, một trận đấu ngắn hơn cũng sẽ hợp lệ. Nhưng vì công cụ regex tham lam theo mặc định, những thứ đó là không đủ cho công cụ regex

Được rồi, vậy làm thế nào chúng ta có thể làm một trận đấu không tham lam?

Python Regex Kết hợp không tham lam

Đối sánh không tham lam có nghĩa là công cụ regex khớp với càng ít ký tự càng tốt—để nó vẫn có thể khớp với mẫu trong chuỗi đã cho

Ví dụ: regex

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
04 sẽ khớp với càng ít
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt trong chuỗi của bạn
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5. Như vậy là khớp với ký tự đầu tiên
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 là xong. Sau đó, nó chuyển sang ký tự thứ hai (cũng là ký tự khớp), v.v.

Nói cách khác, các bộ định lượng không tham lam cung cấp cho bạn kết quả khớp ngắn nhất có thể từ một vị trí nhất định trong chuỗi

Bạn có thể làm cho các bộ định lượng mặc định

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
2 không tham lam bằng cách thêm ký hiệu dấu chấm hỏi
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
56 vào chúng.
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
00,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
02 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
03. chúng “tiêu thụ” hoặc khớp càng ít ký tự càng tốt để mẫu biểu thức chính quy vẫn được thỏa mãn

Dưới đây là một số ví dụ cho thấy cách hoạt động của kết hợp không tham lam

Toán tử dấu hỏi không tham lam (??)

Hãy bắt đầu với dấu chấm hỏi (toán tử không hoặc một)

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0

Trong trường hợp đầu tiên, bạn sử dụng regex zero-or-one

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
05. Nó tham lam nên nó khớp với một ký tự
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 nếu có thể

Trong trường hợp thứ hai, bạn sử dụng phiên bản không-hoặc-một không tham lam

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
33. Nó khớp với số không
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 nếu có thể. Lưu ý rằng nó di chuyển từ trái sang phải để khớp với chuỗi rỗng và “tiêu thụ” nó. Chỉ sau đó, nó không thể khớp với chuỗi rỗng nữa nên buộc phải khớp với ký tự
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 đầu tiên. Nhưng sau đó, bạn có thể tự do khớp lại chuỗi trống. Mẫu khớp đầu tiên với chuỗi rỗng này và chỉ sau đó khớp với
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 nếu nó thực sự cần thiết lặp lại. Đó là lý do tại sao mô hình kỳ lạ này xảy ra

Toán tử dấu hoa thị không tham lam (*?)

Hãy bắt đầu với dấu hoa thị (toán tử 0 hoặc nhiều)

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0

Trước tiên, bạn sử dụng biểu thức chính quy không có hoặc nhiều dấu hoa thị

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
07. Nó tham lam nên khớp với càng nhiều ký tự
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt

Thứ hai, bạn sử dụng phiên bản không-hoặc-một không tham lam

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
39. Một lần nữa, nó khớp với 0
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 nếu có thể. Chỉ khi nó đã khớp với 0 ký tự ở một vị trí nhất định, nó sẽ khớp với một ký tự ở vị trí đó, "tiêu thụ" nó và tiếp tục

Toán tử cộng không tham lam (+?)

Hãy bắt đầu với dấu cộng (toán tử một hoặc nhiều)

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0

Đầu tiên, bạn sử dụng một hoặc nhiều cộng regex

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3. Nó tham lam nên nó khớp với càng nhiều ký tự
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 càng tốt (nhưng ít nhất là một ký tự)

Thứ hai, bạn sử dụng phiên bản một hoặc nhiều phiên bản không tham lam

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
04. Trong trường hợp này, công cụ regex chỉ khớp với một ký tự
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4, sử dụng ký tự đó và tiếp tục với ký tự khớp tiếp theo

Hãy tóm tắt những gì bạn đã học được cho đến nay

Trận đấu tham lam và không tham lam – Đâu là sự khác biệt?

Đưa ra một mẫu có bộ định lượng (e. g. toán tử dấu hoa thị) cho phép công cụ biểu thức chính quy khớp với mẫu nhiều lần

Một chuỗi đã cho có thể khớp với biểu thức chính quy theo nhiều cách. Ví dụ: cả hai chuỗi con

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
4 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
8 đều hợp lệ khi khớp với mẫu
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
07 trong chuỗi
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5

Vì vậy, sự khác biệt giữa trận đấu tham lam và không tham lam là như sau. Khớp tham lam sẽ cố gắng khớp càng nhiều lần lặp lại của mẫu được định lượng càng tốt. Đối sánh không tham lam sẽ cố gắng đối sánh càng ít lần lặp lại của mẫu được định lượng càng tốt

Ví dụ Trận đấu tham lam và không tham lam

Hãy xem xét một loạt các ví dụ giúp bạn hiểu sự khác biệt giữa đối sánh tham lam và không tham lam trong Python

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1

Đảm bảo rằng bạn hoàn toàn hiểu những ví dụ đó trước khi tiếp tục. Nếu bạn không, vui lòng đọc lại các đoạn trước

Cái nào nhanh hơn. Tham lam vs Không tham lam?

Xem xét rằng các bộ định lượng tham lam khớp với số lượng mẫu tối đa và không tham lam tối thiểu, liệu có sự khác biệt nào về hiệu suất không?

Câu hỏi tuyệt vời

Thật vậy, một số điểm chuẩn cho thấy rằng có sự khác biệt đáng kể về hiệu suất. bộ định lượng tham lam chậm hơn 100% trong các thử nghiệm thực tế trên dữ liệu điểm chuẩn

Vì vậy, nếu bạn tối ưu hóa cho tốc độ và bạn không quan tâm đến các đối sánh tham lam hay không tham lam—và bạn không biết bất cứ điều gì khác—hãy sử dụng công cụ định lượng không tham lam

Tuy nhiên, sự thật không đơn giản như vậy. Ví dụ: hãy xem xét thí nghiệm cơ bản sau đây làm sai lệch giả thuyết trước đó rằng phiên bản không tham lam nhanh hơn

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
2

Tôi đã sử dụng công cụ kiểm tra tốc độ timeit cho phép đưa vào một số câu lệnh Python đơn giản và kiểm tra xem chúng chạy trong bao lâu. Theo mặc định, câu lệnh đã truyền được thực thi 1.000.000 lần

Bạn có thể thấy sự khác biệt hiệu suất đáng chú ý hơn 300%. Phiên bản không tham lam chậm hơn ba lần so với phiên bản tham lam

Tại sao vậy?

lý do là lại. phương thức findall() trả về danh sách các chuỗi con phù hợp. Đây là đầu ra mà cả hai câu lệnh sẽ tạo ra

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
5

Bạn có thể thấy rằng phiên bản tham lam tìm thấy một trận đấu và hoàn thành nó. Phiên bản không tham lam tìm thấy 25 kết quả phù hợp dẫn đến chi phí bộ nhớ và xử lý nhiều hơn

Vậy điều gì sẽ xảy ra nếu bạn sử dụng lại. phương thức search() chỉ trả về kết quả khớp đầu tiên thay vì kết quả lại. findall() trả về tất cả các kết quả phù hợp?

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
3

Như mong đợi, điều này thay đổi mọi thứ một lần nữa. Cả hai tìm kiếm regex đều mang lại một kết quả duy nhất, nhưng kết quả không tham lam ngắn hơn nhiều. nó khớp với chuỗi rỗng

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
019 chứ không phải toàn bộ chuỗi
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
00. Tất nhiên, điều này nhanh hơn một chút

Tuy nhiên, sự khác biệt là không đáng kể trong ví dụ tối thiểu này

Còn nữa. Tham lam, ngoan ngoãn, lười biếng, hữu ích, chiếm hữu

Trong bài viết này, tôi đã phân loại thế giới biểu thức chính quy thành các bộ định lượng tham lam và không tham lam. Nhưng bạn có thể phân biệt hạng người “không tham lam” hơn nữa

Tiếp theo, tôi sẽ cung cấp cho bạn một cái nhìn tổng quan ngắn dựa trên bài viết tuyệt vời này về các thuật ngữ quan trọng nhất về vấn đề này

  • Tham. khớp càng nhiều phiên bản của mẫu định lượng càng tốt
  • ngoan ngoãn. khớp với nhiều trường hợp của mẫu được định lượng miễn là nó vẫn khớp với mẫu tổng thể—nếu điều này là có thể. Lưu ý rằng cái mà tôi gọi là “tham lam” trong bài viết này thực ra là “ngoan ngoãn”
  • Lười biếng. khớp với một vài trường hợp của mẫu được định lượng khi cần. Đây là điều mà tôi gọi là “không tham lam” trong bài viết này
  • sở hữu. không bao giờ từ bỏ một trận đấu một phần. Vì vậy, công cụ regex thậm chí có thể không tìm thấy kết quả khớp thực sự tồn tại—chỉ vì nó quá tham lam. Điều này rất bất thường và bạn sẽ không thấy nó nhiều trong thực tế

Nếu bạn muốn tìm hiểu thêm về những điều đó, tôi khuyên bạn nên đọc hướng dẫn trực tuyến tuyệt vời này

Đi đâu từ đây

Bản tóm tắt. Bạn đã học được rằng các bộ định lượng tham lam

>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
0 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
1 khớp với càng nhiều lần lặp lại của mẫu được định lượng càng tốt. Các bộ định lượng không tham lam
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
00,
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
01 và
>>> import re
>>> re.findall('a?', 'aaaa')
['a', 'a', 'a', 'a', '']
>>> re.findall('a*', 'aaaa')
['aaaa', '']
>>> re.findall('a+', 'aaaa')
['aaaa']
>>> re.findall('a{3}', 'aaaa')
['aaa']
>>> re.findall('a{1,2}', 'aaaa')
['aa', 'aa']
02 khớp với càng ít lần lặp lại của mẫu được định lượng càng tốt

Nếu bạn muốn thành thạo Python và các biểu thức chính quy, hãy tham gia học viện email miễn phí của tôi—thật thú vị

Regex hài hước

Trăn regex tham lam
Đợi đã, quên thoát khỏi một không gian. Weeeeee[taptaptap]eeeeee. (nguồn)

Khóa học Python Regex

Các kỹ sư của Google là những bậc thầy về biểu thức chính quy. Công cụ tìm kiếm Google là một công cụ xử lý văn bản khổng lồ trích xuất giá trị từ hàng nghìn tỷ trang web.   

Các kỹ sư của Facebook là những bậc thầy về biểu thức chính quy. Các mạng xã hội như Facebook, WhatsApp và Instagram kết nối con người qua tin nhắn văn bản.  

Các kỹ sư của Amazon là những bậc thầy về biểu thức chính quy. Gã khổng lồ thương mại điện tử vận ​​chuyển sản phẩm dựa trên mô tả sản phẩm bằng văn bản. Biểu thức chính quy thống trị trò chơi khi xử lý văn bản đáp ứng khoa học máy tính.  

Nếu bạn cũng muốn trở thành bậc thầy về biểu thức chính quy, hãy xem khóa học Python regex toàn diện nhất hành tinh

Trăn regex tham lam

Trăn regex tham lam

Chris

Trong khi làm việc với tư cách là một nhà nghiên cứu trong các hệ thống phân tán, Dr. Christian Mayer tìm thấy tình yêu của mình với việc dạy sinh viên khoa học máy tính

Để giúp sinh viên đạt được mức độ thành công Python cao hơn, anh ấy đã thành lập trang web giáo dục lập trình Finxter. com. Ông là tác giả của cuốn sách lập trình nổi tiếng Python One-Liners (NoStarch 2020), đồng tác giả của loạt sách tự xuất bản Coffee Break Python, người đam mê khoa học máy tính, cộng tác viên tự do và chủ sở hữu của một trong 10 blog Python lớn nhất thế giới

Niềm đam mê của anh ấy là viết, đọc và mã hóa. Nhưng niềm đam mê lớn nhất của anh ấy là phục vụ các lập trình viên đầy tham vọng thông qua Finxter và giúp họ nâng cao kỹ năng của mình. Bạn có thể tham gia học viện email miễn phí của anh ấy tại đây