2010-09-21 31 views
9

Tôi đang sử dụng đoạn mã sau:hành vi khác nhau giữa re.finditer và re.findall

CARRIS_REGEX=r'<th>(\d+)</th><th>([\s\w\.\-]+)</th><th>(\d+:\d+)</th><th>(\d+m)</th>' 
pattern = re.compile(CARRIS_REGEX, re.UNICODE) 
matches = pattern.finditer(mailbody) 
findall = pattern.findall(mailbody) 

Nhưng finditer và findall đang tìm những điều khác nhau. Findall thực sự tìm thấy tất cả các kết quả phù hợp trong chuỗi đã cho. Nhưng người tìm kiếm chỉ tìm thấy người đầu tiên, trả về một trình lặp với chỉ một phần tử.

Làm cách nào để làm cho trình tìm kiếm và tìm thấy hoạt động theo cùng một cách?

Cảm ơn

+0

Bạn đang sử dụng trình vòng lặp hoặc xác định số lượng kết quả sẽ trả về? – geoffspear

+0

sử dụng cho phù hợp trong các trận đấu và in chúng. cảm ơn. – simao

+0

Bạn có thể đăng nội dung thư mà bạn đang gặp sự cố này không? – kindall

Trả lời

20

Tôi không thể tái tạo ở đây. Đã thử nó với cả Python 2.7 và 3.1.

Một khác biệt giữa finditerfindall là số cũ trả về đối tượng đối sánh regex trong khi cột kia trả về một nhóm các nhóm chụp phù hợp (hoặc toàn bộ kết quả nếu không có nhóm chụp).

Vì vậy

import re 
CARRIS_REGEX=r'<th>(\d+)</th><th>([\s\w\.\-]+)</th><th>(\d+:\d+)</th><th>(\d+m)</th>' 
pattern = re.compile(CARRIS_REGEX, re.UNICODE) 
mailbody = open("test.txt").read() 
for match in pattern.finditer(mailbody): 
    print(match) 
print() 
for match in pattern.findall(mailbody): 
    print(match) 

in

<_sre.SRE_Match object at 0x00A63758> 
<_sre.SRE_Match object at 0x00A63F98> 
<_sre.SRE_Match object at 0x00A63758> 
<_sre.SRE_Match object at 0x00A63F98> 
<_sre.SRE_Match object at 0x00A63758> 
<_sre.SRE_Match object at 0x00A63F98> 
<_sre.SRE_Match object at 0x00A63758> 
<_sre.SRE_Match object at 0x00A63F98> 

('790', 'PR. REAL', '21:06', '04m') 
('758', 'PORTAS BENFICA', '21:10', '09m') 
('790', 'PR. REAL', '21:14', '13m') 
('758', 'PORTAS BENFICA', '21:21', '19m') 
('790', 'PR. REAL', '21:29', '28m') 
('758', 'PORTAS BENFICA', '21:38', '36m') 
('758', 'SETE RIOS', '21:49', '47m') 
('758', 'SETE RIOS', '22:09', '68m') 

Nếu bạn muốn đầu ra tương tự từ finditer như bạn đang nhận được từ findall, bạn cần

for match in pattern.finditer(mailbody): 
    print(tuple(match.groups())) 
+0

Tôi không biết tại sao nó không hoạt động. Tôi gỡ bỏ cài đặt python 2,5 và nâng cấp lên 2,6 và nó làm việc ngay bây giờ: | – simao

+0

@JeromeJ: Cảm ơn bạn đã bình luận (đã xóa) - bạn hoàn toàn đúng. –

4

Bạn không thể khiến chúng hoạt động theo cùng một cách vì chúng khác nhau. Nếu bạn thực sự muốn tạo ra một danh sách các kết quả từ finditer, sau đó bạn có thể sử dụng một danh sách hiểu:

>>> [match for match in pattern.finditer(mailbody)] 
[...] 

Nói chung, sử dụng một vòng lặp for để truy cập các trận đấu được trả về bởi re.finditer:

>>> for match in pattern.finditer(mailbody): 
...  ... 
+0

Vâng, tôi biết điều đó. Vấn đề là, họ không tìm thấy những trận đấu giống nhau. findall tìm tất cả các kết quả phù hợp trong chuỗi. finditer chỉ tìm thấy cái đầu tiên và có, tôi đã sử dụng vòng lặp for để duyệt qua tất cả các phần tử trong trình lặp. – simao

+6

'[đối sánh cho phù hợp trong pattern.finditer (mailbody)]' chỉ là một cách chậm hơn và ít có thể đọc được khi nói 'danh sách (pattern.finditer (mailbody))' – aaronasterling

+0

Cảm ơn @ArronMcSmooth, điểm tốt. –

4

lại. findall (pattern.string)

findall() trả về tất cả các trận đấu không chồng chéo của mẫu trong chuỗi như một danh sách các chuỗi.

re.finditer()

finditer() trả về đối tượng callable.

Trong cả hai hàm, chuỗi được quét từ trái sang phải và kết quả phù hợp được trả về theo thứ tự tìm thấy.

Các vấn đề liên quan