re.findall ('(ab | cd)', स्ट्रिंग) बनाम re.findall ('(ab | cd) +', स्ट्रिंग)


18

पायथन नियमित अभिव्यक्ति में, मैं इस विलक्षण समस्या का सामना करता हूं। आप के बीच के अंतर पर निर्देश दे सकते हैं re.findall('(ab|cd)', string)और re.findall('(ab|cd)+', string)?

import re

string = 'abcdla'
result = re.findall('(ab|cd)', string)
result2 = re.findall('(ab|cd)+', string)
print(result)
print(result2)

वास्तविक आउटपुट है:

['ab', 'cd']
['cd']

मैं उलझन में हूँ कि दूसरा परिणाम क्यों नहीं होता है 'ab'?


re.findall ('(ab | cd)', स्ट्रिंग) को ['ab', 'cd'] re.findall ('(ab | cd) +', string) मिलता है ['cd']
rock

जवाबों:


15

+एक रिपीट क्वांटिफायर है जो एक या अधिक बार मेल खाता है। रेगेक्स में (ab|cd)+, आप + का उपयोग करके कैप्चर समूह को दोहरा रहे हैं (ab|cd)। यह केवल अंतिम पुनरावृत्ति पर कब्जा करेगा।

आप इस व्यवहार के बारे में निम्नानुसार कर सकते हैं:

कहते हैं कि आपका तार है abcdlaऔर regex है (ab|cd)+। रेगेक्स इंजन समूह के लिए 0 और 1 के बीच के मैच का पता abलगाएगा और कैप्चर समूह से बाहर निकल जाएगा। फिर यह +क्वांटिफायर देखता है और इसलिए समूह को फिर से पकड़ने की कोशिश करता है और cdपदों 2 और 3 के बीच कब्जा करेगा ।


आप सभी पुनरावृत्तियों कैप्चर करना चाहते हैं, तो आप चाहिए दोहरा समूह पर कब्जा के साथ बजाय ((ab|cd)+)जो मैचों abcdऔर cd। आप आंतरिक समूह गैर कैप्चरिंग कर सकते हैं के रूप में हम आंतरिक समूह मैचों के बारे में परवाह नहीं है के साथ ((?:ab|cd)+)जो मैचोंabcd

https://www.regular-expressions.info/captureall.html

डॉक्स से,

मान लीजिए कि आपकी तरह एक टैग से मिलान करना चाहते हैं !abc!या !123!। केवल इन दो संभव हो रहे हैं, और आप कैप्चर करना चाहते abcया 123यह पता लगाने की जो टैग आपको मिला है। यह काफी आसान है: !(abc|123)!चाल चलेगा।

आइए अब कहना है कि टैग के कई दृश्यों को शामिल कर सकते abcहैं और 123, जैसे !abc123!या !123abcabc!। त्वरित और आसान उपाय है !(abc|123)+!। यह नियमित अभिव्यक्ति वास्तव में इन टैग से मेल खाएगी। हालाँकि, यह टैग के लेबल को कैप्चरिंग ग्रुप में कैप्चर करने के लिए हमारी आवश्यकता को पूरा नहीं करता है। जब यह रेगेक्स मैच करता है !abc123!, तो कैप्चरिंग ग्रुप केवल स्टोर करता है 123। जब यह मेल खाता है !123abcabc!, तो यह केवल स्टोर करता है abc


क्या आप इस तथ्य को स्पष्ट करते हुए कुछ डॉक से लिंक कर सकते हैं कि + केवल अंतिम पुनरावृत्ति को कैप्चर करता है, और कैप्चर समूह क्या है?
गुलज़ार Gul

1
@ गुलज़ार ने जवाब अपडेट किया। आप यहां कैप्चर समूहों के बारे में पढ़ सकते हैं - regular-expressions.info/refcapture.html
शशांक V

@ शशांक, धन्यवाद, आपका उत्तर ठीक वही है जिसकी मुझे आवश्यकता है। ईमानदारी से धन्यवाद
रॉक

अगर यह आपके प्रश्न को हल करता है तो कृपया उत्तर स्वीकार करें।
शशांक V

ब्रैकेट के साथ पूरे रेगेक्स को घेरने की कोई आवश्यकता नहीं है। सिर्फ '(?:ab|cd)+'काम करेंगे।
22

5

मुझे नहीं पता कि यह चीजें और अधिक स्पष्ट करेंगी, लेकिन आइए हम यह कल्पना करने की कोशिश करें कि एक साधारण तरीके से हुड के नीचे क्या होता है, हम मिलान करने के लिए क्या होगा।

   # group(0) return the matched string the captured groups are returned in groups or you can access them
   # using group(1), group(2).......  in your case there is only one group, one group will capture only 
   # one part so when you do this
   string = 'abcdla'
   print(re.match('(ab|cd)', string).group(0))  # only 'ab' is matched and the group will capture 'ab'
   print(re.match('(ab|cd)+', string).group(0)) # this will match 'abcd'  the group will capture only this part 'cd' the last iteration

findallउसी समय स्ट्रिंग का मिलान करें और उसका उपभोग करें, आइए कल्पना करें कि इस REGEX के साथ क्या होता है '(ab|cd)':

      'abcdabla' ---> 1:   match: 'ab' |  capture : ab  | left to process:  'cdabla'
      'cdabla'   ---> 2:   match: 'cd' |  capture : cd  | left to process:  'abla'
      'abla'     ---> 3:   match: 'ab' |  capture : ab  | left to process:  'la'
      'la'       ---> 4:   match: '' |  capture : None  | left to process:  ''

      --- final : result captured ['ab', 'cd', 'ab']  

अब उसी के साथ '(ab|cd)+'

      'abcdabla' ---> 1:   match: 'abcdab' |  capture : 'ab'  | left to process:  'la'
      'la'       ---> 2:   match: '' |  capture : None  | left to process:  ''
      ---> final result :   ['ab']  

मुझे उम्मीद है कि यह बात थोड़ी साफ हो जाएगी।


0

इसलिए, मेरे लिए भ्रामक हिस्सा तथ्य यह था कि

यदि पैटर्न में एक या अधिक समूह मौजूद हैं, तो समूहों की सूची लौटाएं;

डॉक्स

इसलिए यह आपको एक पूर्ण मैच नहीं बल्कि केवल एक कैप्चर का मैच लौटा रहा है। यदि आप इस समूह को कैप्चर नहीं कर रहे हैं (re.findall('(?:ab|cd)+', string), तो यह वापस आ जाएगा जैसा ["abcd"]कि मुझे शुरू में उम्मीद थी


सुनिश्चित नहीं है कि आप क्या उम्मीद करते हैं या नहीं
रियाद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.