2010-01-03 44 views
7

Tôi nghĩ tôi sẽ viết một số mã nhanh để tải xuống số lượng "người hâm mộ" mà trang Facebook có.Ký tự đại diện phù hợp với chuỗi trong tìm kiếm regex Python

Vì một số lý do, mặc dù số lần lặp lại hợp lý mà tôi đã thử, tôi không thể lấy mã sau để chọn số lượng người hâm mộ trong HTML. Không có giải pháp nào khác mà tôi tìm thấy trên web cũng khớp chính xác với regex trong trường hợp này. Chắc chắn nó có thể có một số ký tự đại diện giữa hai bit phù hợp?

Văn bản tôi muốn đối sánh là "6 trong số X người hâm mộ", trong đó X là số lượng người hâm mộ tùy ý một trang - Tôi muốn lấy số này.

Tôi đã nghĩ đến việc bỏ phiếu cho dữ liệu này liên tục và ghi vào một tệp nhưng tôi chưa nhận được thông tin đó. Tôi cũng tự hỏi liệu điều này có đi đúng hướng hay không, vì đoạn mã có vẻ khá clunky. :)

import urllib 
import re 

fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft') 
pattern = "6 of(.*)fans" #this wild card doesnt appear to work? 
compiled = re.compile(pattern) 

for lines in fbhandle.readlines(): 
     ms = compiled.match(lines) 
     print ms #debugging 
     if ms: break 
#ms.group() 
print ms 
fbhandle.close() 
+1

* không hoạt động * không phải là mô tả sự cố –

+0

sidenote: bạn nên đặt tên 'dòng' 'dòng' – miku

+1

Vui lòng đăng văn bản bạn đang cố gắng so khớp và (nếu có thể) kết quả bạn mong đợi. – Mike

Trả lời

9
import urllib 
import re 

fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft') 
pattern = "6 of(.*)fans" #this wild card doesnt appear to work? 
compiled = re.compile(pattern) 

ms = compiled.search(fbhandle.read()) 
print ms.group(1).strip() 
fbhandle.close() 

Bạn cần thiết để sử dụng re.search() để thay thế. Sử dụng re.match() cố gắng khớp mẫu với toàn bộ tài liệu toàn bộ tài liệu, nhưng thực sự bạn chỉ đang cố gắng khớp một phần bên trong tài liệu. Mã trên được in: 79,110. Tất nhiên, điều này có thể sẽ là một số khác nhau vào thời điểm nó được điều hành bởi người khác.

+1

cảm ơn rất nhiều - hoạt động tốt. im không chắc chắn tôi hoàn toàn hiểu được sự khác biệt mặc dù - match() sẽ được sử dụng trong trường hợp một số loại bool eval đã được thực hiện trên một chuỗi nhỏ (ish)? – oneAday

+2

@oneAday: giải thích tốt về sự khác biệt giữa 'match' và' search': http://www.amk.ca/python/howto/regex/regex.html#SECTION000720000000000000000 – bernie

+0

@oneAday: tại sao không chấp nhận câu trả lời này nếu nó việc cho bạn? – bernie

0

không cần regex

import urllib 
fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft') 
for line in fbhandle.readlines(): 
    line=line.rstrip().split("</span>") 
    for item in line: 
     if ">Fans<" in item: 
      rind=item.rindex("<span>") 
      print "-->",item[rind:].split()[2] 

đầu ra

$ ./python.py 
--> 79,133 
10

Evan Fosmark đã đã đưa ra một câu trả lời tốt. Đây chỉ là thông tin thêm.

Bạn có dòng này:

pattern = "6 of(.*)fans" 

Nói chung, đây không phải là một biểu thức chính quy tốt. Nếu văn bản đầu vào là:

"6 của 99 người hâm mộ trong toàn bộ thiên hà của các fan"

Sau đó các nhóm phù hợp (những thứ bên trong dấu ngoặc đơn) sẽ là:

"99 người hâm mộ trong cả thiên hà của "

Vì vậy, chúng tôi muốn một mẫu sẽ chỉ lấy những gì bạn muốn, ngay cả với văn bản đầu vào ngớ ngẩn như trên.

Trong trường hợp này, nó không thực sự quan trọng nếu bạn phù hợp với không gian màu trắng, bởi vì khi bạn chuyển đổi một chuỗi thành một số nguyên, khoảng trắng sẽ bị bỏ qua. Nhưng hãy viết mẫu để bỏ qua khoảng trắng.

Với ký tự đại diện *, có thể khớp với một chuỗi có độ dài bằng không. Trong trường hợp này, tôi nghĩ bạn luôn muốn một trận đấu không trống, vì vậy bạn muốn sử dụng + để khớp một hoặc nhiều ký tự.

Python có kết hợp không tham lam, vì vậy bạn có thể viết lại với điều đó. Các chương trình cũ hơn với các biểu thức thông thường có thể không có kết hợp không tham lam, vì vậy tôi cũng sẽ đưa ra một mẫu không yêu cầu tham lam.

Vì vậy, mô hình phi tham lam:

pattern = "6 of\s+(.+?)\s+fans" 

Các khác một:

pattern = "6 of\s+(\S+)\s+fans" 

\s có nghĩa là "bất kỳ không gian trắng" và sẽ phù hợp với một không gian, một tab, và một vài khác ký tự (chẳng hạn như "nguồn cấp dữ liệu biểu mẫu"). \S có nghĩa là "bất kỳ không phải không gian trắng" và khớp với bất kỳ thứ gì mà \s sẽ không phải là phù hợp.

Các mô hình đầu tiên thực hiện tốt hơn so với mô hình đầu tiên của bạn với các văn bản đầu vào ngớ ngẩn:

"6 của 99 người hâm mộ trong toàn bộ thiên hà của các fan"

Nó sẽ trả về một nhóm trận đấu chỉ 99.

Nhưng thử văn bản này khác ngớ ngẩn đầu vào:

"6 của 99 fan cuồng"

Nó sẽ trả về một nhóm phù hợp của 99 crazed.

Mẫu thứ hai sẽ không khớp với nhau, bởi vì từ "điên cuồng" không phải là từ "người hâm mộ".

Hmm. Dưới đây là một mô hình cuối cùng mà nên luôn luôn làm điều đúng ngay cả với các văn bản đầu vào ngớ ngẩn:

pattern = "6 of\D*?(\d+)\D*?fans" 

\d khớp với bất kỳ chữ số ('0'-'9'). \D khớp với bất kỳ chữ số nào.

này thành công sẽ phù hợp với bất cứ điều gì đó là điều khiển từ xa không mơ hồ:

"6 của 99 người hâm mộ trong toàn bộ thiên hà của các fan"

Nhóm trận đấu sẽ 99.

"6 của 99 fan cuồng"

Nhóm trận đấu sẽ 99.

"6/99 41 người hâm mộ"

Nó sẽ không khớp, vì có số thứ hai trong đó.

Để tìm hiểu thêm về biểu thức chính quy của Python, bạn có thể đọc variouswebpages. Để có lời nhắc nhanh, bên trong trình thông dịch Python, hãy làm:

>>> import re 
>>> help(re) 

Khi bạn "cào" văn bản từ trang web, đôi khi bạn có thể chạy nhiều mã HTML. Nói chung, cụm từ thông dụng không phải là công cụ tốt để bỏ qua đánh dấu HTML hoặc XML (xem here); bạn có thể sẽ làm tốt hơn để sử dụng Beautiful Soup để phân tích cú pháp HTML và trích xuất văn bản, theo sau là cụm từ thông dụng để lấy văn bản bạn thực sự muốn.

Tôi hy vọng điều này thú vị và/hoặc giáo dục.

+0

+1 cho chiều rộng và khối lượng tuyệt đối – bernie

+0

thú vị VÀ giáo dục - tuyệt vời. cảm ơn rất nhiều. – oneAday

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