2011-02-05 5 views
9

पायथन में रेगेक्स काम करने का तरीका इतनी तीव्रता से परेशान है कि यह मुझे प्रत्येक गुजरने वाले दूसरे के साथ अधिक क्रोधित बनाता है।क्यों rystring 'मैचों के साथ मेरा regex पाइथन का उपयोग कर' स्ट्रिंग 'नहीं?

मैं समझता हूँ कि यह एक परिणाम देता है: यहाँ मेरी समस्या है

re.search(r'\bmi\b', 'grand rapids, mi 49505) 

जबकि इस कार्य नहीं करता:

re.search('\bmi\b', 'grand rapids, mi 49505) 

और वह ठीक है। मुझे यह बहुत मिलता है।

regex = '|'.join(['\b' + str(state) + '\b' for state in states]) 

मैं अब re.search(regex, 'grand rapids, mi 49505') करते हैं, यह एक ही कारण मेरी दूसरी search() उदाहरण में विफल रहता है के लिए विफल रहता है: अब, मैं एक नियमित अभिव्यक्ति है कि इस तरह से उत्पन्न किया जा रहा है।

मेरा प्रश्न: क्या मैं ऐसा करने का प्रयास कर रहा हूं?

+3

नोट: वर्ग कोष्ठक निरर्थक (वास्तव में, हानिकारक हैं: के बीच का अंतर 'ओ (एन) 'और' ओ (1)' मेमोरी खपत), इसके बजाए [जनरेटर अभिव्यक्ति] (http://docs.python.org/tutorial/classes.html#generator-expressions) का उपयोग करें। – delnan

उत्तर

14

anwser ही

regex = '|'.join([r'\b' + str(state) + r'\b' for state in states]) 

इसके पीछे कारण यह है कि है 'आर' उपसर्ग ने पाइथन को उस स्ट्रिंग का विश्लेषण न करने के लिए कहा है जिसे आप पास करते हैं। यदि आप स्ट्रिंग से पहले 'आर' नहीं डालते हैं, तो पाइथन ब्रेक लाइन (\ n), टैब (\ t) और ऐसे में प्रवेश करने की अनुमति देने के लिए, किसी विशेष चार में '\' द्वारा किसी भी चार को चालू करने का प्रयास करेगा। आसानी से।

जब आप '\b' करते हैं, आप, एक स्ट्रिंग बनाने यह विश्लेषण, और बदलने के लिए 'बैकस्पेस' में '\ बी' अजगर बताओ, जबकि जब आप r'\b', अजगर बस दुकान '\' तो 'बी', और यह करने के रेगेक्स के लिए आप क्या चाहते हैं। रेगेक्स पैटर्न के रूप में उपयोग की जाने वाली स्ट्रिंग के लिए हमेशा 'आर' का उपयोग करें।

'आर' नोटेशन को 'कच्ची स्ट्रिंग' कहा जाता है, लेकिन यह भ्रामक है, क्योंकि पाइथन आंतरिक में कच्ची स्ट्रिंग जैसी कोई चीज़ नहीं है। पाइथन को बहुत स्मार्ट होने से बचने के लिए बस एक तरीका के रूप में इसके बारे में सोचें।

पायथन < 3.0, u'string 'में एक और संकेत है, जो स्ट्रिंग को यूनिकोड के रूप में स्टोर करने के लिए पाइथन को बताता है। आप दोनों को गठबंधन कर सकते हैं: ur"é\n" "\ bé" को यूनिकोड के रूप में स्टोर करेगा, जबकि u"é\n" "é" को फिर एक लाइन ब्रेक स्टोर करेगा।

कुछ अपने कोड बेहतर बनाने के तरीके:

regex = '|'.join(r'\b' + str(state) + r'\b' for state in states) 

हटाया अतिरिक्त []। यह पाइथन को स्मृति में स्टोर करने के लिए बताता है कि आप जो मूल्य उत्पन्न कर रहे हैं उसकी सूची। हम इसे यहां कर सकते हैं क्योंकि हम आपके द्वारा बनाई गई सूची का पुन: उपयोग करने की योजना नहीं बनाते हैं क्योंकि आप इसे सीधे अपने join() में उपयोग करते हैं और कहीं और नहीं।

regex = '|'.join(r'\b%s\b' % state for state in states) 

यह स्वचालित रूप से स्ट्रिंग रूपांतरण का ख्याल रखेगा और छोटा और क्लीनर होगा।जब आप पायथन में स्ट्रिंग को प्रारूपित करते हैं, तो % operator के बारे में सोचें।

यदि राज्यों में राज्य ज़िप कोड की एक सूची है, तो स्ट्रिंग के रूप में संग्रहीत किया जाना चाहिए, int के रूप में नहीं। उस मामले में, आप प्रकार कास्टिंग छोड़ सकते हैं और यह और भी छोटा कर सकते हैं:

regex = r'\b%s\b' % r'\b|\b'.join(states) 

अंततः, आप रेगुलर एक्सप्रेशन से बिल्कुल भी जरूरत नहीं हो सकती है। आप सभी की परवाह की जाँच करने के लिए है, तो अगर जिप कोड में से एक दिया स्ट्रिंग में है, तो आप सिर्फ in (एक स्ट्रिंग किसी सूची में है अगर तरह की जांच एक iterable में अगर एक आइटम है,) का उपयोग कर सकते हैं:

matches = [s for s in states if s in 'grand rapids, mi 49505'] 

अंतिम शब्द

मैं समझता हूँ कि आप निराश जब एक नई भाषा सीखने हो सकता है लेकिन आपके सवाल का एक उचित शीर्षक देने के लिए समय लगता है। इस वेबसाइट में, शीर्षक को एक प्रश्न चिह्न के साथ समाप्त होना चाहिए और समस्या के बारे में विशिष्ट विवरण देना चाहिए।

+0

कैसे एक स्पष्टीकरण के बारे में? – delnan

+1

आपका फ्रेंच दिखा रहा है। सूची> सूची। – ash

+2

अरे यह। रुको, मैं इतालवी हो सकता है! –

4

समाधान वह है जिसे आपने ऊपर दिए गए उदाहरण में स्वयं का उपयोग किया: कच्चे तार।

regex = '|'.join(r'\b' + str(state) + r'\b' for state in states) 

(ध्यान दें कि मैं भी अतिरिक्त कोष्ठक हटा दिया, एक जनरेटर अभिव्यक्ति में सूची समझ मोड़।)

+0

हालांकि कच्चे तारों की आवश्यकता क्यों है? – cledoux

+1

एक स्ट्रिंग में बस '\ b' को एक अनुक्रम अनुक्रम के रूप में व्याख्या किया जाता है और एक बेल नियंत्रण कोड (मुझे लगता है) उत्पन्न करता है। जब आप (परिणामी) रेगेक्स को बचाना अनुक्रम शामिल करना चाहते हैं, तो आपको यह सुनिश्चित करना होगा कि संपूर्ण अनुक्रम स्ट्रिंग में शामिल है। इसलिए आपको बैकस्लैश से बचने की ज़रूरत है: '\\ b' जिसके परिणामस्वरूप स्ट्रिंग के भीतर '\ b' होता है। – poke

+0

@ char8705: मेरे anwser में इसके लिए एक कारण जोड़ा। –

2

कुंजी '\ b' और r '\ b' के बीच अंतर को समझ रही है। इस उत्पादन में प्रयोग में नहीं परिणामों में इन टाइपिंग:

>>> '\b' 
'\x08' 
>>> r'\b' 
'\\b' 

तो जब भी आप एक regex में एक बैकस्लैश में टाइप करें, आप इसे कच्चे स्ट्रिंग संकेतन का उपयोग करके बच चाहिए।

+0

यह भ्रामक है। पायथन आंतरिक रूप से आर '\ b' को '\\ b' के रूप में स्टोर नहीं करता है। यह आईडीईएल और अधिकांश पायथन शेल है जो आपको इस तरह प्रदर्शित करता है कि आपको अंदर क्या है इसका संकेत मिल सके। लेकिन अगर आप प्रिंट करते हैं तो आपको वही नहीं मिलेगा। यह सभी नए लोगों को भ्रमित करने जा रहा है। –

0

के इन दो तार टूट करते हैं:

r'\bmi\b' 

अजगर रूप छह वर्ण लंबा (बैकस्लैश, पत्र बी, आदि) से ऊपर स्ट्रिंग व्याख्या करता है। एक कच्ची स्ट्रिंग पाइथन के \ b का बैकस्पेस में अनुवाद को दबा देती है।

फिर दो अक्षर \ और एक शब्द को तोड़ने के रूप में व्याख्या करता है।

'\bmi\b' 

अजगर रूप चार वर्ण लंबा (बैकस्पेस, पत्र बी, आदि) से ऊपर स्ट्रिंग व्याख्या करता है।
re अब उन शाब्दिक चार पात्रों की व्याख्या करने और देखने के लिए विशेष कुछ भी नहीं देखता है।

तो नीचे निर्माण backspaces, नहीं शब्द टूट जाता है की तलाश में है:

regex = '|'.join(['\b' + str(state) + '\b' for state in states]) 

इस प्रयास करें (छोड़ने str, राज्य पहले से ही एक स्ट्रिंग होना चाहिए):

regex = '|'.join([r'\b' + state + r'\b' for state in states]) 

शब्द को तोड़ने नहीं करता है ' टी को हर या अभिव्यक्ति में संसाधित करने की आवश्यकता नहीं है।इसे बाहर खींच सरल में शामिल होने:

regex = r'\b(' + '|'.join(states) + r')\b' 

के बाद से Pythonistas आमतौर पर regexes पर भ्रूभंग, साथ ही कर सकता है एक पठनीय एक:

import re 

pattern = re.compile(r''' 
    (?ix) # ignore case, verbose 
    \b # word break 
    ( # begin group 1 
    AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA| 
    HI|ID|IL|IN|IA|KS|KY|LA|ME|MD| 
    MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ| 
    NM|NY|NC|ND|OH|OK|OR|PA|RI|SC| 
    SD|TN|TX|UT|VT|VA|WA|WV|WI|WY 
    )  # end group 1 
    \b # word break 
    ''') 

m = pattern.search('Grand Rapids, MI 49505') 
if m: 
    print m.group(1) 
+0

"चूंकि पाइथोनिस्टा आमतौर पर रेगेक्स पर फहराया जाता है ..." दिलचस्प। कैसे? इसके बजाय आप इसका क्या उपयोग करेंगे? –

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