पहले मैच रेगेक्स के साथ वापसी स्ट्रिंग


91

मैं रेगेक्स का पहला मैच हासिल करना चाहता हूं।

इस मामले में, मुझे एक सूची मिली:

text = 'aa33bbb44'
re.findall('\d+',text)

['33', '44']

मैं सूची का पहला तत्व निकाल सकता है:

text = 'aa33bbb44'
re.findall('\d+',text)[0]

'33'

लेकिन यह तभी काम करता है जब कम से कम एक मैच हो, अन्यथा मुझे एक त्रुटि मिलेगी:

text = 'aazzzbbb'
re.findall('\d+',text)[0]

IndexError: लिस्ट इंडेक्स ऑफ़ रेंज

किस मामले में मैं एक फ़ंक्शन को परिभाषित कर सकता हूं:

def return_first_match(text):
    try:
        result = re.findall('\d+',text)[0]
    except Exception, IndexError:
        result = ''
    return result

क्या किसी नए फ़ंक्शन को परिभाषित किए बिना उस परिणाम को प्राप्त करने का एक तरीका है?


मेरे लिए स्वीकृत जवाब से काम नहीं चला। मुझे एरे इंडेक्स एक्सेस को हटाने और len(re.findAll)==0इसके बजाय चेक का उपयोग करना पड़ा ।
विशाल 10

जवाबों:


110

आप ''जोड़कर अपने regex में डिफ़ॉल्ट एम्बेड कर सकते हैं |$:

>>> re.findall('\d+|$', 'aa33bbb44')[0]
'33'
>>> re.findall('\d+|$', 'aazzzbbb')[0]
''
>>> re.findall('\d+|$', '')[0]
''

re.searchदूसरों द्वारा इंगित किए गए कार्यों के साथ भी :

>>> re.search('\d+|$', 'aa33bbb44').group()
'33'
>>> re.search('\d+|$', 'aazzzbbb').group()
''
>>> re.search('\d+|$', '').group()
''

महान, खोज करता है / .group का फ़ंडॉल / [0] पर कोई लाभ है?
लुइस रेमन रामिरेज़ रोड्रिगेज

6
@LuisRamonRamirezRodriguez वैसे तो यह बंद हो सकता है जैसे ही यह एक मैच मिला, बाकी टेक्स्ट को प्रोसेस नहीं करना है और सभी मैचों को स्टोर नहीं करना है। इसलिए यह अधिक कुशल है। साथ ही, @TimPeters ने कहा, " शाब्दिक रूप से यही आप चाहते हैं" । यह एक फायदा हो सकता है जब आप या कोई और इसे पढ़ता है और आश्चर्य करता है कि "क्यों findallइस्तेमाल किया गया था ?"
स्टीफन पोचमैन

43

यदि आपको केवल पहले मैच की आवश्यकता है, तो re.searchइसके बजाय उपयोग करें re.findall:

>>> m = re.search('\d+', 'aa33bbb44')
>>> m.group()
'33'
>>> m = re.search('\d+', 'aazzzbbb')
>>> m.group()
Traceback (most recent call last):
  File "<pyshell#281>", line 1, in <module>
    m.group()
AttributeError: 'NoneType' object has no attribute 'group'

तो आप mएक जाँच शर्त के रूप में उपयोग कर सकते हैं :

>>> m = re.search('\d+', 'aa33bbb44')
>>> if m:
        print('First number found = {}'.format(m.group()))
    else:
        print('Not Found')


First number found = 33

13

मैं साथ जाता हूँ:

r = re.search("\d+", ch)
result = return r.group(0) if r else ""

re.searchकेवल वैसे भी स्ट्रिंग में पहले मैच की तलाश है, इसलिए मुझे लगता है कि यह आपके इरादे को उपयोग करने की तुलना में थोड़ा अधिक स्पष्ट करता है findall


9

आपको बिल्कुल भी उपयोग नहीं करना चाहिए .findall()- .search()जो आप चाहते हैं। यह सबसे बाएं मैच को ढूंढता है, जो आप चाहते हैं (या Noneयदि कोई मैच मौजूद नहीं है तो रिटर्न )।

m = re.search(pattern, text)
result = m.group(0) if m else ""

आप एक समारोह में है कि आप के लिए करना चाहते हैं। यह असामान्य है, तो कोई मुकाबला नहीं पाया जाता है एक खाली स्ट्रिंग वापस जाने के लिए है, जिसके कारण ऐसा कुछ नहीं में बनाया गया है चाहते हैं। यह असंभव है के बारे में उलझन में पाने के लिए है कि क्या .search()अपने आप ही पाता पर एक मैच (यह रिटर्न Noneअगर उसने ऐसा नहीं किया है, या एक SRE_Matchवस्तु अगर यह किया है)।


3

तुम कर सकते हो:

x = re.findall('\d+', text)
result = x[0] if len(x) > 0 else ''

ध्यान दें कि आपका प्रश्न regex से संबंधित नहीं है। बल्कि, आप किसी एरे से एक तत्व को सुरक्षित रूप से कैसे पा सकते हैं, अगर इसके पास कोई नहीं है।


2
मैं यहां 'l' (x)> 0 'को' x 'से बदल दूंगा।
उल्फ असलाक

1

हो सकता है कि इनपुट डेटा के अधिक से अधिक मात्रा में आपके वांछित टुकड़े के न होने की स्थिति में यह थोड़ा बेहतर हो, क्योंकि इसके अलावा अधिक लागत है।

def return_first_match(text):
    result = re.findall('\d+',text)
    result = result[0] if result else ""
    return result
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.