2010-01-03 22 views
7

मैंने सोचा कि मैं एक फेसबुक पेज के "प्रशंसकों" की संख्या डाउनलोड करने के लिए कुछ त्वरित कोड लिखूंगा।पाइथन रेगेक्स खोज में एक स्ट्रिंग से मेल खाता वाइल्डकार्ड

कुछ कारणों से, मैंने कोशिश की गई उचित संख्या के बावजूद, मुझे HTML में प्रशंसकों की संख्या चुनने के लिए निम्न कोड नहीं मिल सकता है। वेब पर मिले अन्य समाधानों में से कोई भी इस मामले में रेगेक्स से सही ढंग से मेल नहीं खाता है। निश्चित रूप से दो मिलान बिट्स के बीच कुछ वाइल्डकार्ड होना संभव है?

जिस पाठ के साथ मैं मिलान करना चाहता हूं वह है "एक्स प्रशंसकों" 6, जहां एक्स एक पृष्ठ के प्रशंसकों की मनमानी संख्या है - मैं यह नंबर प्राप्त करना चाहता हूं।

मैं इस डेटा को अंतःक्रियात्मक रूप से मतदान करने और फ़ाइल में लिखने की सोच रहा था लेकिन मुझे अभी तक इसके आसपास नहीं मिला है। मैं यह भी सोच रहा हूं कि यह सही दिशा में आगे बढ़ रहा है, क्योंकि कोड बहुत खराब लगता है। :)

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

* काम नहीं दिख रहा है * कोई समस्या नहीं है –

+0

sidenote: आपको 'लाइन' 'लाइन' – miku

+1

नाम देना चाहिए, कृपया जिस पाठ को आप मिलान करने का प्रयास कर रहे हैं उसे पोस्ट करें और (यदि संभव हो) परिणाम जो आप उम्मीद करते हैं। – Mike

उत्तर

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() 

इसके बजाय आप re.search() उपयोग करने के लिए की जरूरत है। re.match() का उपयोग पूरे दस्तावेज़ के विरुद्ध पैटर्न से मिलान करने का प्रयास करता है, लेकिन वास्तव में आप दस्तावेज़ के अंदर एक टुकड़े से मिलान करने की कोशिश कर रहे हैं। प्रिंट के ऊपर कोड: 79,110। बेशक, यह किसी और द्वारा चलाए जाने के समय शायद एक अलग संख्या होगी।

+1

बहुत बहुत धन्यवाद - बस ठीक काम करता है। मुझे यकीन नहीं है कि मैं भेद को पूरी तरह से समझता हूं - मैच() उन मामलों में उपयोग किया जाएगा जहां छोटे (आईएसएच) स्ट्रिंग पर कुछ प्रकार के बूल eval किया जा रहा था? – oneAday

+2

@oneday: 'मिलान' और 'खोज' के बीच अंतर का अच्छा स्पष्टीकरण: http://www.amk.ca/python/howto/regex/regex.html#SECTION000720000000000000000 – bernie

+0

@oneday: अगर यह जवाब स्वीकार नहीं किया जाता है आपके लिए काम करता है? – bernie

0

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] 

उत्पादन

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

इवान Fosmark पहले से ही एक अच्छा जवाब दिया की जरूरत नहीं है। यह सिर्फ अधिक जानकारी है। यह एक अच्छा रेगुलर एक्सप्रेशन नहीं है,

pattern = "6 of(.*)fans" 

सामान्य में:

आप इस रेखा है। यदि इनपुट पाठ था:

"99 में से 6 प्रशंसकों की पूरी आकाशगंगा में प्रशंसकों" तो फिर मैच समूह (कोष्ठकों के अंदर सामान) होगा:

"99 पूरे में प्रशंसकों "

की गैलेक्सी तो, हम एक पैटर्न चाहते हैं जो ऊपर की तरह एक मूर्ख इनपुट पाठ के साथ भी आप जो चाहते हैं उसे पकड़ लेंगे।

इस मामले में, यह वास्तव में कोई फर्क नहीं पड़ता कि आप सफेद स्थान से मेल खाते हैं, क्योंकि जब आप एक स्ट्रिंग को एक पूर्णांक में परिवर्तित करते हैं, तो सफेद स्थान को अनदेखा किया जाता है। लेकिन चलो सफेद जगह को अनदेखा करने के लिए पैटर्न लिखें।

* वाइल्डकार्ड के साथ, लंबाई शून्य की एक स्ट्रिंग से मिलान करना संभव है। इस मामले में मुझे लगता है कि आप हमेशा एक गैर-खाली मैच चाहते हैं, इसलिए आप एक या अधिक वर्णों से मेल खाने के लिए + का उपयोग करना चाहते हैं।

पायथन में गैर-लालची मिलान उपलब्ध है, इसलिए आप इसके साथ फिर से लिख सकते हैं। नियमित अभिव्यक्ति वाले पुराने कार्यक्रमों में गैर-लालची मिलान नहीं हो सकता है, इसलिए मैं एक ऐसा पैटर्न भी दूंगा जिसके लिए गैर लालची की आवश्यकता नहीं है।

तो, गैर लालची पैटर्न:

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

अन्य एक:

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

\s का अर्थ है "किसी भी सफेद स्थान" और एक जगह, एक टैब, और कुछ अन्य से मेल खाएगी अक्षर (जैसे "फॉर्म फीड")। \S का मतलब है "कोई भी गैर-सफेद-स्थान" और \s मिलान से कुछ भी मेल खाता है।

यह सिर्फ 99 के एक मैच के समूह वापसी होगी "प्रशंसकों की पूरी आकाशगंगा में 99 में से 6 प्रशंसक"

:

पहले पैटर्न मूर्खतापूर्ण इनपुट पाठ के साथ अपना पहला पैटर्न की तुलना में बेहतर है।

लेकिन यह अन्य मूर्खतापूर्ण इनपुट पाठ की कोशिश: यह 99 crazed के एक मैच के समूह वापसी होगी

"99 में से 6 पागल प्रशंसक"

दूसरा पैटर्न बिल्कुल मेल नहीं खाता है, क्योंकि "crazed" शब्द "प्रशंसकों" शब्द नहीं है।

हम्म।

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

\d किसी भी अंकों ('9'-'0') से मेल खाता है: यहाँ एक आखिरी पैटर्न है कि हमेशा भी मूर्खतापूर्ण इनपुट पाठ के साथ सही काम करना चाहिए। \D किसी भी गैर-अंकों से मेल खाता है।

मैच समूह 99 हो जाएगा "प्रशंसकों की पूरी आकाशगंगा में 99 में से 6 प्रशंसक"

:

यह सफलतापूर्वक कुछ भी दूर से गैर अस्पष्ट है कि मेल खाएगी।

"99 में से 6 पागल प्रशंसक"

मैच समूह 99 हो जाएगा।

यह मेल नहीं खाएगी "99 41 प्रशंसकों के 6"

, क्योंकि वहाँ वहाँ में एक दूसरे नंबर था।

पायथन नियमित अभिव्यक्तियों के बारे में अधिक जानने के लिए, आप variouswebpages पढ़ सकते हैं। एक त्वरित अनुस्मारक के लिए, पायथन दुभाषिया के अंदर, कार्य करें:

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

जब आप किसी वेब पृष्ठ से पाठ "स्क्रैप" कर रहे हैं, तो आप कभी कभी HTML कोड के afoul चलाने हो सकता है। सामान्य रूप से, नियमित अभिव्यक्ति HTML या XML मार्कअप को अनदेखा करने के लिए एक अच्छा उपकरण नहीं है (here देखें); आप एचटीएमएल को पार्स करने और पाठ को निकालने के लिए Beautiful Soup का उपयोग करने के लिए बेहतर प्रदर्शन करेंगे, जिसके बाद आप वास्तव में इच्छित पाठ को पकड़ने के लिए एक नियमित अभिव्यक्ति के बाद।

मुझे आशा है कि यह दिलचस्प और/या शैक्षिक था।

+0

+1 चौड़ाई और मात्रा – bernie

+0

दिलचस्प और शैक्षिक - शानदार के लिए +1। बहुत बहुत धन्यवाद। – oneAday

संबंधित मुद्दे