Cách sử dụng mô-đun biểu thức chính quy Python re (đối sánh, tìm kiếm, phụ, v.v.)

Kinh doanh

Để thực hiện xử lý biểu thức chính quy trong Python, chúng tôi sử dụng mô-đun re từ thư viện chuẩn. Nó cho phép bạn trích xuất, thay thế và tách chuỗi bằng cách sử dụng các mẫu biểu thức chính quy.

Trong phần này, trước tiên chúng tôi sẽ giải thích các chức năng và phương thức của mô-đun re.

  • Biên dịch các mẫu biểu thức chính quy:compile()
  • đối tượng phù hợp
  • Kiểm tra xem phần đầu của chuỗi có khớp không, hãy giải nén:match()
  • Kiểm tra các trận đấu không giới hạn từ đầu:search()
  • Kiểm tra xem toàn bộ chuỗi có khớp không:fullmatch()
  • Nhận danh sách tất cả các bộ phận phù hợp:findall()
  • Nhận tất cả các phần phù hợp dưới dạng một trình lặp:finditer()
  • Thay thế bộ phận phù hợp:sub(),subn()
  • Tách chuỗi bằng các mẫu biểu thức chính quy:split()

Sau đó, tôi sẽ giải thích các ký tự meta (ký tự đặc biệt) và chuỗi đặc biệt của biểu thức chính quy có thể được sử dụng trong mô-đun re. Về cơ bản, nó là cú pháp biểu thức chính quy tiêu chuẩn, nhưng hãy cẩn thận về việc đặt cờ (đặc biệt là re.ASCII).

  • Siêu ký tự biểu thức chính quy, chuỗi đặc biệt và cảnh báo trong Python
  • Đặt cờ
    • Giới hạn trong các ký tự ASCII:re.ASCII
    • Không phân biệt chữ hoa chữ thường:re.IGNORECASE
    • Khớp phần đầu và phần cuối của mỗi dòng:re.MULTILINE
    • Chỉ định nhiều cờ
  • Trận đấu tham lam và không tham lam

Biên dịch mẫu biểu thức chính quy: compile ()

Có hai cách để thực hiện xử lý biểu thức chính quy trong mô-đun re.

Chạy với chức năng

Đầu tiên là một chức năng.re.match(),re.sub()Các chức năng như thế này có sẵn để thực hiện trích xuất, thay thế và các quy trình khác bằng cách sử dụng các mẫu biểu thức chính quy.

Chi tiết của các hàm sẽ được mô tả sau, nhưng trong tất cả chúng, đối số đầu tiên là chuỗi của mẫu biểu thức chính quy, tiếp theo là chuỗi được xử lý, v.v. Ví dụ, trong re.sub (), thực hiện thay thế, đối số thứ hai là chuỗi thay thế và đối số thứ ba là chuỗi được xử lý.

import re

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Lưu ý rằng [a-z] trong mẫu biểu thức chính quy trong ví dụ này có nghĩa là bất kỳ ký tự nào từ a đến z (tức là bảng chữ cái viết thường) và + có nghĩa là lặp lại mẫu trước đó (trong trường hợp này là [a-z]) một hoặc nhiều lần. [A-z] + khớp với bất kỳ chuỗi nào lặp lại một hoặc nhiều ký tự chữ cái viết thường.

. là một ký tự meta (một ký tự có ý nghĩa đặc biệt) và phải được thoát bằng dấu gạch chéo ngược.

Vì các chuỗi mẫu biểu thức chính quy thường sử dụng nhiều dấu gạch chéo ngược, nên việc sử dụng các chuỗi thô như trong ví dụ sẽ rất tiện lợi.

Chạy trong một phương thức của một đối tượng mẫu biểu thức chính quy

Cách thứ hai để xử lý biểu thức chính quy trong mô-đun re là phương thức đối tượng mẫu biểu thức chính quy.

Sử dụng re.compile (), bạn có thể biên dịch một chuỗi mẫu biểu thức chính quy để tạo đối tượng mẫu biểu thức chính quy.

p = re.compile(r'([a-z]+)@([a-z]+)\.com')

print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')

print(type(p))
# <class 're.Pattern'>

re.match(),re.sub()Ví dụ, quá trình tương tự như các hàm này có thể được thực thi như các phương thức match (), sub () của các đối tượng biểu thức chính quy.

m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

Tất cả các hàm re.xxx () được mô tả bên dưới cũng được cung cấp dưới dạng các phương thức của đối tượng biểu thức chính quy.

Nếu bạn đang lặp lại một quy trình sử dụng cùng một mẫu, sẽ hiệu quả hơn nếu tạo một đối tượng biểu thức chính quy với re.compile () và sử dụng nó xung quanh.

Trong mã mẫu sau, hàm được sử dụng mà không cần biên dịch để thuận tiện, nhưng nếu bạn muốn sử dụng lặp lại cùng một mẫu, bạn nên biên dịch trước và thực thi nó như một phương thức của một đối tượng biểu thức chính quy.

đối tượng phù hợp

match (), search (), v.v. trả về một đối tượng trùng khớp.

s = 'aaa@xxx.com'

m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(m))
# <class 're.Match'>

Chuỗi và vị trí đã so khớp được lấy bằng các phương thức sau của đối tượng khớp.

  • Nhận vị trí của trận đấu:start(),end(),span()
  • Lấy chuỗi phù hợp:group()
  • Lấy chuỗi cho mỗi nhóm:groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

Nếu bạn đặt một phần của mẫu biểu thức chính quy trong chuỗi với dấu ngoặc đơn (), phần đó sẽ được xử lý dưới dạng một nhóm. Trong trường hợp này, chuỗi của phần khớp với từng nhóm trong nhóm () có thể được lấy dưới dạng một bộ.

m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.groups())
# ('aaa', 'xxx', 'com')

Kiểm tra xem phần đầu của một chuỗi có khớp không, hãy giải nén: match ()

match () trả về một đối tượng khớp nếu phần đầu của chuỗi khớp với mẫu.

Như đã đề cập ở trên, đối tượng khớp có thể được sử dụng để trích xuất chuỗi con đã khớp hoặc chỉ đơn giản là để kiểm tra xem có khớp hay không.

match () sẽ chỉ kiểm tra phần đầu. Nếu không có chuỗi phù hợp ở đầu, nó trả về Không có.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None

Kiểm tra các kết quả phù hợp không giới hạn từ đầu, trích xuất: search ()

Giống như match (), nó trả về một đối tượng match nếu nó khớp.

Nếu có nhiều bộ phận phù hợp, chỉ bộ phận phù hợp đầu tiên sẽ được trả lại.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Nếu bạn muốn lấy tất cả các bộ phận phù hợp, hãy sử dụng findall () hoặc finditer () như được mô tả bên dưới.

Kiểm tra xem toàn bộ chuỗi có khớp không: fullmatch ()

Để kiểm tra xem toàn bộ chuỗi có khớp với mẫu biểu thức chính quy hay không, hãy sử dụng fullmatch (). Điều này rất hữu ích, chẳng hạn, để kiểm tra xem một chuỗi có hợp lệ như một địa chỉ email hay không.

Nếu toàn bộ chuỗi khớp, một đối tượng khớp sẽ được trả về.

s = 'aaa@xxx.com'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

Nếu có các phần chưa khớp (chỉ khớp một phần hoặc không khớp hoàn toàn), Không có phần nào được trả lại.

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

Fullmatch () đã được thêm vào Python 3.4. Nếu bạn muốn làm điều tương tự trong các phiên bản trước, hãy sử dụng match () và ký tự meta phù hợp $ ở cuối. Nếu toàn bộ chuỗi từ đầu đến cuối không khớp, nó trả về Không có.

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

Nhận danh sách tất cả các bộ phận phù hợp: findall ()

findall () trả về danh sách tất cả các chuỗi con phù hợp. Lưu ý rằng các phần tử của danh sách không phải là các đối tượng khớp mà là các chuỗi.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']

Có thể kiểm tra số lượng các bộ phận phù hợp bằng cách sử dụng hàm len () cài sẵn, hàm này trả về số lượng phần tử trong danh sách.

print(len(result))
# 3

Việc nhóm với dấu ngoặc đơn () trong một mẫu biểu thức chính quy trả về một danh sách các bộ giá trị có các phần tử là các chuỗi của mỗi nhóm. Điều này tương đương với các nhóm () trong đối tượng so khớp.

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

Các dấu ngoặc đơn của nhóm () có thể được lồng vào nhau, vì vậy nếu bạn cũng muốn nhận toàn bộ kết quả phù hợp, chỉ cần đặt toàn bộ kết hợp trong dấu ngoặc đơn ().

result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]

Nếu không tìm thấy kết quả phù hợp, một bộ giá trị trống sẽ được trả về.

result = re.findall('[0-9]+', s)
print(result)
# []

Nhận tất cả các phần phù hợp dưới dạng một trình lặp: finditer ()

finditer () trả về tất cả các phần phù hợp dưới dạng một trình lặp. Các phần tử không phải là các chuỗi như findall (), mà là các đối tượng khớp với nhau, vì vậy bạn có thể nhận được vị trí (chỉ mục) của các phần đã khớp.

Bản thân trình lặp không thể được in ra bằng print () để lấy nội dung của nó. Nếu bạn sử dụng hàm tích hợp next () hoặc câu lệnh for, bạn có thể lấy từng nội dung một.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>

print(type(result))
# <class 'callable_iterator'>

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

Nó cũng có thể được chuyển đổi thành một danh sách với list ().

l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]

print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(l[0]))
# <class 're.Match'>

print(l[0].span())
# (0, 11)

Nếu bạn muốn có được vị trí của tất cả các phần phù hợp, ký hiệu hiểu danh sách sẽ thuận tiện hơn danh sách ().

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

Trình lặp lấy ra các phần tử theo thứ tự. Lưu ý rằng nếu bạn cố gắng trích xuất thêm các phần tử sau khi đến cuối, bạn sẽ không còn gì cả.

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

print(list(result))
# []

Thay thế các bộ phận phù hợp: sub (), subn ()

Sử dụng sub (), bạn có thể thay thế phần đã khớp bằng một chuỗi khác. Chuỗi được thay thế sẽ được trả về.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

print(type(result))
# <class 'str'>

Khi nhóm với dấu ngoặc đơn (), chuỗi được so khớp có thể được sử dụng trong chuỗi được thay thế.

Theo mặc định, những điều sau được hỗ trợ: Lưu ý rằng đối với các chuỗi bình thường không phải là chuỗi thô, dấu gạch chéo ngược phải được liệt kê trước dấu gạch chéo ngược để thoát khỏi dấu gạch chéo ngược.

\1Dấu ngoặc đơn đầu tiên
\2Dấu ngoặc thứ hai
\3Dấu ngoặc thứ ba
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

?P<xxx>
Nếu bạn đặt tên cho nhóm bằng cách viết cái này vào đầu dấu ngoặc của mẫu biểu thức chính quy, bạn có thể chỉ định nhóm bằng cách sử dụng tên thay vì số, như được hiển thị bên dưới.
\g<xxx>

result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

Số đối số chỉ định số lượng thay thế tối đa. Chỉ số đếm từ phía bên trái sẽ được thay thế.

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net

subn () trả về một bộ giá trị của chuỗi được thay thế (giống như giá trị trả về của sub ()) và số phần được thay thế (số khớp với mẫu).

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

Phương thức chỉ định đối số giống như sub (). Bạn có thể sử dụng phần được nhóm bằng dấu ngoặc đơn hoặc chỉ định số lượng đối số.

result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)

Tách chuỗi bằng các mẫu biểu thức chính quy: split ()

split () chia chuỗi ở phần khớp với mẫu và trả về nó dưới dạng danh sách.

Lưu ý rằng kết quả phù hợp đầu tiên và cuối cùng sẽ chứa các chuỗi trống ở đầu và cuối danh sách kết quả.

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

Đối số maxsplit chỉ định số lượng tách (phần) tối đa. Chỉ số đếm từ phía bên trái sẽ được tách ra.

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

Siêu ký tự biểu thức chính quy, chuỗi đặc biệt và cảnh báo trong Python

Các ký tự meta biểu thức chính quy chính (ký tự đặc biệt) và chuỗi đặc biệt có thể được sử dụng trong mô-đun Python 3 re như sau

siêu nhân vậtnội dung
.Bất kỳ ký tự đơn nào không phải là một dòng mới (bao gồm một dòng mới với cờ DOTALL)
^Phần đầu của chuỗi (cũng khớp với phần đầu của mỗi dòng với cờ MULTILINE)
$Phần cuối của chuỗi (cũng khớp với phần cuối của mỗi dòng với cờ MULTILINE)
*Lặp lại mẫu trước đó nhiều hơn 0 lần
+Lặp lại mẫu trước đó ít nhất một lần.
?Lặp lại mẫu trước đó 0 hoặc 1 lần
{m}Lặp lại mẫu trước đó m lần
{m, n}Mẫu cuối cùng.m~nlặp lại
[]Một tập hợp các ký tự[]Khớp với bất kỳ một trong những ký tự này
|HOẶCA|BKhớp với mẫu A hoặc B
trình tự đặc biệtnội dung
\dSố thập phân Unicode (giới hạn ở số ASCII bởi cờ ASCII)
\D\dCó nghĩa là ngược lại với điều này.
\sCác ký tự khoảng trắng Unicode (giới hạn ở các ký tự khoảng trắng ASCII bởi cờ ASCII)
\S\sCó nghĩa là ngược lại với điều này.
\wCác ký tự từ Unicode và dấu gạch dưới (giới hạn ở các ký tự chữ và số ASCII và dấu gạch dưới của cờ ASCII)
\W\wCó nghĩa là ngược lại với điều này.

Không phải tất cả chúng đều được liệt kê trong bảng này. Xem tài liệu chính thức để có danh sách đầy đủ.

Cũng lưu ý rằng một số ý nghĩa khác nhau trong Python 2.

Đặt cờ

Như được hiển thị trong bảng trên, một số ký tự meta và chuỗi đặc biệt thay đổi chế độ của chúng tùy thuộc vào cờ.

Chỉ có các lá cờ chính được che ở đây. Xem tài liệu chính thức để biết phần còn lại.

Giới hạn đối với các ký tự ASCII: re.ASCII

\wĐiều này cũng sẽ khớp với các ký tự kanji byte kép, ký tự chữ và số, v.v. theo mặc định cho chuỗi Python 3. Nó không tương đương với cái sau vì nó không phải là một biểu thức chính quy chuẩn.[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None

Nếu bạn chỉ định re.ASCII cho các cờ đối số trong mỗi hàm hoặc thêm cờ nội dòng sau vào đầu chuỗi mẫu biểu thức chính quy, nó sẽ chỉ khớp với các ký tự ASCII (nó sẽ không khớp với các ký tự chữ và số tiếng Nhật byte kép, v.v. .).
(?a)
Trong trường hợp này, hai điều sau đây là tương đương.
\w#ERROR![a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None

m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None

Điều tương tự cũng áp dụng khi biên dịch với re.compile (). Sử dụng cờ đối số hoặc cờ nội tuyến.

p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

ASCII cũng có sẵn ở dạng ngắn lại. A. Bạn có thể sử dụng một trong hai.

print(re.ASCII is re.A)
# True

\ W, ngược lại với \ W, cũng bị ảnh hưởng bởi re.ASCII và cờ nội tuyến.

m = re.match(r'\W+', '漢字ABC123')
print(m)
# None

m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

Như với \ w, hai ký tự sau đối sánh với cả ký tự byte đơn và byte kép theo mặc định, nhưng bị giới hạn ở ký tự byte đơn nếu re.ASCII hoặc cờ nội tuyến được chỉ định.

  • Phù hợp với những con số\d
  • Khớp một khoảng trống\s
  • Đối sánh không phải số\D
  • Đối sánh với bất kỳ không phải khoảng trắng nào.\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None

m = re.match(r'\s+', ' ')  # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>

m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None

Không phân biệt chữ hoa chữ thường:re.IGNORECASE

Theo mặc định, nó phân biệt chữ hoa chữ thường. Để khớp cả hai, bạn cần bao gồm cả chữ hoa và chữ thường trong mẫu.

re.IGNORECASENếu điều này được chỉ định, nó sẽ khớp phân biệt chữ hoa chữ thường. Tương đương với cờ i trong biểu thức chính quy chuẩn.

m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

Bạn có thể sử dụng ít hơn hoặc bằng.

  • cờ nội tuyến(?i)
  • viết tắtre.I

Khớp phần đầu và phần cuối của mỗi dòng:re.MULTILINE

^Các ký tự meta trong biểu thức chính quy này khớp với phần đầu của chuỗi.

Theo mặc định, chỉ phần đầu của toàn bộ chuỗi được so khớp, nhưng phần sau cũng sẽ khớp với phần đầu của mỗi dòng. Tương đương với cờ m trong biểu thức chính quy chuẩn.
re.MULTILINE

s = '''aaa-xxx
bbb-yyy
ccc-zzz'''

print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz

result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']

result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']

result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']

$Khớp với phần cuối của chuỗi. Theo mặc định, chỉ phần cuối của toàn bộ chuỗi được so khớp.
re.MULTILINENếu bạn chỉ định điều này, nó cũng sẽ khớp với cuối mỗi dòng.

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

Bạn có thể sử dụng ít hơn hoặc bằng.

  • cờ nội tuyến(?m)
  • viết tắtre.M

Chỉ định nhiều cờ

|Nếu bạn muốn bật nhiều cờ cùng một lúc, hãy sử dụng điều này. Trong trường hợp cờ nội dòng, mỗi ký tự phải được theo sau bởi một chữ cái như hình dưới đây.
(?am)

s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''

print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz

result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']

result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']

result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']

Trận đấu tham lam và không tham lam

Đây là một vấn đề chung với biểu thức chính quy, không chỉ là vấn đề với Python, nhưng tôi sẽ viết về nó vì nó có xu hướng khiến tôi gặp rắc rối.

Theo mặc định, sau đây là một kết hợp tham lam, phù hợp với chuỗi dài nhất có thể.

  • *
  • +
  • ?
s = 'aaa@xxx.com, bbb@yyy.com'

m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>

print(m.group())
# aaa@xxx.com, bbb@yyy.com

Các ? sau nó sẽ dẫn đến một kết quả phù hợp tối thiểu, không tham lam, khớp với chuỗi ngắn nhất có thể.

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

Lưu ý rằng kết hợp tham lam mặc định có thể khớp với các chuỗi không mong muốn.

Copied title and URL