it-swarm-vi.com

Sự khác biệt giữa re.search và re.match là gì?

Sự khác biệt giữa các hàm search()match() trong mô đun Python re là gì?

Tôi đã đọc tài liệ ( tài liệu hiện tại ), nhưng dường như tôi không bao giờ nhớ nó. Tôi tiếp tục phải tìm kiếm nó và học lại nó. Tôi hy vọng rằng ai đó sẽ trả lời rõ ràng bằng các ví dụ để (có lẽ) nó sẽ dính vào đầu tôi. Hoặc ít nhất tôi sẽ có một nơi tốt hơn để trở lại với câu hỏi của mình và sẽ mất ít thời gian hơn để tìm hiểu lại nó.

427
Daryl Spitzer

re.match được neo ở đầu chuỗi. Điều đó không liên quan gì đến các dòng mới, vì vậy nó không giống như sử dụng ^ trong mẫu.

Như tài liệu re.match nói:

Nếu không có hoặc nhiều ký tự ở đầu của chuỗi khớp với mẫu biểu thức chính quy, hãy trả về một thể hiện MatchObject tương ứng. Trả về None nếu chuỗi không khớp với mẫu; lưu ý rằng điều này khác với một trận đấu có độ dài bằng không.

Lưu ý: Nếu bạn muốn xác định vị trí một trận đấu ở bất kỳ đâu trong chuỗi, thay vào đó, hãy sử dụng search().

re.search tìm kiếm toàn bộ chuỗi, vì tài liệu nói :

Quét qua chuỗi để tìm vị trí trong đó mẫu biểu thức chính quy tạo ra một kết quả khớp và trả về một thể hiện MatchObject tương ứng. Trả về None nếu không có vị trí nào trong chuỗi khớp với mẫu; lưu ý rằng điều này khác với việc tìm một kết quả có độ dài bằng không tại một số điểm trong chuỗi.

Vì vậy, nếu bạn cần khớp ở đầu chuỗi hoặc để khớp toàn bộ chuỗi, hãy sử dụng match. Nó nhanh hơn Nếu không, hãy sử dụng search.

Tài liệu này có một phần cụ thể cho match so với search cũng bao gồm các chuỗi nhiều dòng:

Python cung cấp hai hoạt động nguyên thủy khác nhau dựa trên các biểu thức thông thường: match chỉ kiểm tra một kết quả khớp ở đầu của chuỗi, trong khi search kiểm tra khớp ở bất cứ đâu trong chuỗi (đây là những gì Perl làm theo mặc định).

Lưu ý rằng match có thể khác với search ngay cả khi sử dụng biểu thức chính quy bắt đầu bằng '^': '^' chỉ khớp với ở đầu chuỗi hoặc trong chế độ MULTILINE ngay lập tức theo dòng mới. Hoạt động của match thành công chỉ khi mẫu khớp với lúc bắt đầu của chuỗi bất kể chế độ hoặc tại vị trí bắt đầu được cung cấp bởi đối số pos tùy chọn bất kể dòng mới có trước nó hay không.

Bây giờ, nói đủ rồi. Thời gian để xem một số mã ví dụ:

# example code:
string_with_newlines = """something
someotherthing"""

import re

print re.match('some', string_with_newlines) # matches
print re.match('someother', 
               string_with_newlines) # won't match
print re.match('^someother', string_with_newlines, 
               re.MULTILINE) # also won't match
print re.search('someother', 
                string_with_newlines) # finds something
print re.search('^someother', string_with_newlines, 
                re.MULTILINE) # also finds something

m = re.compile('thing$', re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines, 
               re.MULTILINE) # also matches
432
nosklo

search tìm thứ gì đó ở bất cứ đâu trong chuỗi và trả về một đối tượng khớp.

match tìm thứ gì đó tại bắt đầ của chuỗi và trả về một đối tượng khớp.

82
Dhanasekaran Anbalagan

re.searchtìm kiếm es cho mẫu trong toàn chuỗi, trong khi re.match không không tìm kiếm mẫu; nếu không, nó không có lựa chọn nào khác ngoài khớp nó ở đầu chuỗi.

46
xilun

kết hợp nhanh hơn nhiều so với tìm kiếm, vì vậy thay vì thực hiện regex.search ("Word"), bạn có thể thực hiện regex.match ((. *?) Word (. *?)) và đạt được hàng tấn hiệu suất nếu bạn đang làm việc với hàng triệu mẫu.

Nhận xét này từ @ivan_bilan theo câu trả lời được chấp nhận ở trên khiến tôi suy nghĩ nếu như vậy hack thực sự tăng tốc bất cứ điều gì, vì vậy hãy tìm hiểu xem có bao nhiêu tấn hiệu suất bạn sẽ thực sự đạt được.

Tôi đã chuẩn bị bộ kiểm tra sau:

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_Word():
    Word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
    Word = ''.join(Word)
    return Word

wordlist = [generate_Word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', Word) for Word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', Word) for Word in wordlist]
print('match:', time.time() - start)

Tôi đã thực hiện 10 phép đo (1M, 2M, ..., 10M từ) cho tôi âm mưu sau:

match vs. search regex speedtest line plot

Các dòng kết quả là đáng ngạc nhiên (thực sự không đáng ngạc nhiên) thẳng. Và hàm searchnhanh hơn (một chút) với sự kết hợp mẫu cụ thể này. Đạo đức của bài kiểm tra này: Tránh tối đa hóa mã của bạn.

25
Jeyekomon

Sự khác biệt là, re.match() đánh lừa bất kỳ ai quen với Perl , grep hoặc sed khớp biểu thức chính quy và re.search() thì không. :-)

Tỉnh táo hơn, Như John D. Cook nhận xét , re.match() "hành xử như thể mọi mô hình đều có ^ chuẩn bị trước." Nói cách khác, re.match('pattern') bằng re.search('^pattern'). Vì vậy, nó neo bên trái của một mô hình. Nhưng nó cũng không neo bên phải của mẫu: vẫn yêu cầu chấm dứt $.

Thẳng thắn đưa ra những điều trên, tôi nghĩ rằng re.match() nên không được chấp nhận. Tôi sẽ quan tâm để biết lý do nó nên được giữ lại.

25
CODE-REaD

bạn có thể tham khảo ví dụ dưới đây để hiểu hoạt động của re.match và re.search

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match sẽ không trả về, nhưng re.search sẽ trả về abc.

25
ldR

re.match cố gắng khớp một mẫu ở đầu chuỗi. re.search cố gắng khớp mẫu trong suốt chuỗi cho đến khi tìm thấy kết quả khớp.

14
cschol

Ngắn hơn nhiều:

  • search quét toàn bộ chuỗi.

  • match Chỉ bắt đầu chuỗi.

Theo dõi Ex nói rằng:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
1
U9-Forward