python Re.search में आरंभ/समाप्ति तर्क का उपयोग करते समय regex में $ और ^ के बीच असंगतता?




(3)

यह मुझे गलत लगता है, या कम से कम असंगत है।

नहीं, endpos व्याख्या पायथन के बाकी हिस्सों के अनुरूप है, यह शुरुआती pos जो प्रलेखन के रूप में असंगत है:

पैरामीटर पॉस स्ट्रिंग में एक इंडेक्स देता है जहां खोज शुरू करनी है; यह 0. को डिफॉल्ट करता है। यह स्ट्रिंग को स्लाइस करने के लिए पूरी तरह से बराबर नहीं है; '^' पैटर्न चरित्र स्ट्रिंग की वास्तविक शुरुआत से मेल खाता है

मैंने जो पढ़ा है, उससे ^ को एक स्ट्रिंग की शुरुआत और $ अंत का मिलान करना चाहिए। हालाँकि, re.search() , ऐसा लगता है कि ^ का व्यवहार ठीक काम करना जारी है, जबकि $ 'ब्रेक'। उदाहरण:

>>> a = re.compile( "^a" )
>>> print a.search( "cat", 1, 3 )
None

यह मुझे सही लगता है - 'a' स्ट्रिंग की शुरुआत में नहीं है, भले ही वह खोज के शुरू में हो।

>>> a = re.compile( "a$" )
>>> print a.search( "cat", 0, 2 )
<_sre.SRE_Match object at 0x7f41df2334a8>

यह मुझे गलत लगता है, या कम से कम असंगत है।

re मॉड्यूल के प्रलेखन में स्पष्ट रूप से उल्लेख किया गया है कि ^ का व्यवहार re.search के लिए शुरू / समाप्ति तर्क के कारण नहीं बदलता है, लेकिन व्यवहार में कोई परिवर्तन $ (जो मैंने देखा है) के लिए उल्लेख नहीं किया गया है।

क्या कोई समझा सकता है कि चीजों को इस तरह से डिजाइन किया गया था, और / या एक सुविधाजनक समाधान सुझाया गया?

वर्कअराउंड करके, मैं एक रेगेक्स की रचना करना चाहूंगा, जो हमेशा स्ट्रिंग के अंत से मेल खाता हो, तब भी जब कोई अंतिम तर्क का उपयोग पुनः खोज में करता है।

और फिर से खोज क्यों की गई थी:

s.search( string, endPos=len(string) - 1 )

के समान है

s.search( string[:-1] )

कब

s.search( string, startPos=1 )

स्पष्ट रूप से और जानबूझकर के रूप में ही नहीं है

s.search( string[1:] )

यह ^ और $ बीच असंगतता का मुद्दा कम लगता है, और re.search फ़ंक्शन के भीतर असंगतता का अधिक।


संक्षिप्त जवाब

स्ट्रिंग की शाब्दिक शुरुआत या अंत से मिलान करने के लिए \A से और \Z का उपयोग करें। re मॉड्यूल के डॉक्स से संबंधित लाइनें:

6.2.1। नियमित अभिव्यक्ति सिंटैक्स

\A केवल स्ट्रिंग की शुरुआत में मेल खाता है।

\Z केवल स्ट्रिंग के अंत में मेल खाता है।

endpos बारे में चेतावनी

यह "तब भी काम नहीं करेगा जब कोई अंतिम तर्क का पुनः उपयोग करता है"। "स्टार्ट" पैरामीटर endpos विपरीत, जो सिर्फ एक शुरुआती बिंदु को चिह्नित करता है, endpos पैरामीटर का अर्थ है कि खोज (या मैच) स्ट्रिंग के केवल एक हिस्से पर ही आयोजित की जाएगी (जोर जोड़ा):

6.2.3। नियमित अभिव्यक्ति वस्तुओं

regex.search(string[, pos[, endpos]] )

वैकल्पिक पैरामीटर endpos सीमा को endpos है कि स्ट्रिंग कितनी दूर तक खोजा जाएगा; यह वैसा ही होगा जैसे कि स्ट्रिंग वर्णों को लंबा करता है , [...] rx.search(string, 0, 50) rx.search(string[:50], 0) बराबर है।

\Z स्ट्रिंग खोजे जाने वाले स्ट्रिंग के अंत से मेल खाता है, जो कि वास्तव में endpos बदलता है।

पृष्ठभूमि

अधिक परिचित ^ और $ जो आप सोचते हैं कि वे नहीं करते हैं:

^ (कैरेट।) स्ट्रिंग की शुरुआत से मेल खाता है, और MULTILINE मोड में भी प्रत्येक न्यूलाइन के तुरंत बाद मेल खाता है।

$ स्ट्रिंग के अंत से मेल खाती है या स्ट्रिंग के अंत में नई रेखा से पहले, और MULTILINE मोड में भी एक नई रेखा से पहले मेल खाता है। foo दोनों 'foo' और 'foobar' से मेल खाता है, जबकि नियमित अभिव्यक्ति foo$ 'foo' से मेल खाता है। अधिक दिलचस्प बात यह है कि foo.$ के लिए खोज foo.$ 'foo1\nfoo2\n' में foo.$ सामान्य रूप से 'foo2' से मेल खाता है, लेकिन MULTILINE मोड में 'foo1'; 'foo\n' में एक एकल $ लिए खोज करने पर दो (खाली) मैच मिलेंगे: एक नई लाइन से ठीक पहले, और एक स्ट्रिंग के अंत में।

पायथन की नियमित अभिव्यक्तियाँ पर्ल से बहुत प्रभावित हैं, जिसने अपने स्वयं के एक मेजबान के साथ पुराने grep क्षमताओं को बढ़ाया। इसमें मल्टी-लाइन मिलान शामिल था, जिसने ^ जैसे मेटाचेचर्स के बारे में एक प्रश्न उठाया था: क्या यह स्ट्रिंग की शुरुआत या लाइन की शुरुआत से मेल खा रहा था ? जब grep एक समय में केवल एक पंक्ति से मेल grep था, तो वे समान अवधारणाएँ थीं।

जैसा कि आप देख सकते हैं, ^ और $ समाप्त हो गया सब कुछ "स्टार्ट-लाइक" और "एंड-ईश" से मेल खाने की कोशिश कर रहा है। पर्ल ने केवल स्टार्ट-ऑफ-स्ट्रिंग और एंड-ऑफ-स्ट्रिंग से मिलान करने के लिए नए एस्केप सीक्वेंस \A और \z (लोअर-केस) की शुरुआत की।

उन बच अनुक्रमों को पायथन द्वारा अपनाया गया था, लेकिन एक अंतर के साथ: पायथन ने पर्ल के \Z (ऊपरी-मामले) को नहीं अपनाया, जो अंत-के-स्ट्रिंग और विशेष मामले के न्यूलाइन-से-एंड-ऑफ़-स्ट्रिंग दोनों से मेल खाता था ... पार्टनर को यह उम्मीद नहीं थी कि वह उम्मीद करेगा।

(मुझे लगता है कि निरंतरता के लिए पाइथन अपर-केसेड पर्ल के \z , '\Apattern\z' regexes से '\Apattern\z' जो पर्ल बेस्ट प्रैक्टिसेस जैसी पुस्तकों में अनुशंसित थे।)

pos और endpos का इतिहास

ऐसा प्रतीत होता है कि अजीब "वास्तव में स्टार्ट -स्टार्ट पोजिशन नहीं है" pos का अर्थ पैरामीटर जितना ही पुराना है:

  • पायथन 1.4 match फंक्शन डॉक्स (25 अक्टूबर 1996 --- शायद रेगेक्स ऑब्जेक्ट को प्री-डेटिंग) endpos या endpos पैरामीटर को बिल्कुल नहीं दिखाता है।

  • पायथन 1.5 match विधि डॉक्स (17 फरवरी 1998) दोनों नियमित अभिव्यक्ति ऑब्जेक्ट और pos और endpos मापदंडों को पेश करते हैं। यह बताता है कि एक ^ pos मेल खाएगा , हालांकि बाद में संशोधन बताते हैं कि यह एक टाइपो था। (टाइपो की बात करते हुए: ^ चरित्र ही गायब है। यह आया और चला गया, जब तक कि पायथन 2.1 में अच्छे (?) के लिए पुन: प्रकट नहीं हो जाता।)

  • पायथन 1.5.1 match विधि डॉक्स (14 अप्रैल 1998) पिछले डॉक्स को पीछे छोड़ते हुए, "नहीं" डालें।

  • पायथन 1.5.1p1 match विधि डॉक्स (06 अगस्त 1998) pos के अप्रत्याशित प्रभावों को स्पष्ट करता है। वे Python 3.6.1 का pos वर्ड-फॉर-वर्ड के विवरण से मेल खाते हैं ... उस pesky ^ टाइपो को देते हैं या लेते हैं।

मुझे लगता है कि बग-फिक्स रिलीज़ के कुछ महीनों में डॉक्स के लिए कई बदलावों को वास्तविकता के साथ पकड़ने वाले डॉक्स को दर्शाते हैं --- match के डिजाइन में बदलाव नहीं (हालांकि मेरे पास सत्यापित करने के लिए पाइथन 1 झूठ नहीं है)।

python-dev मेलिंग सूची अभिलेखागार केवल 1999 तक वापस चला जाता है, इसलिए जब तक कि पहले के संदेश कहीं और सहेजे नहीं गए थे, मुझे लगता है कि "क्यों" प्रश्न का उत्तर देने से यह अनुमान लगाने की आवश्यकता होगी कि उस कोड को किसने लिखा है, और उनसे पूछ रहा है।


here search() प्रलेखन के अनुसार:

वैकल्पिक पैरामीटर एंडपोज़ सीमा को दर्शाता है कि स्ट्रिंग कितनी दूर तक खोजा जाएगा; यह वैसा ही होगा जैसे कि स्ट्रिंग वर्णों को लंबा करता है, इसलिए केवल पोज़ से लेकर अंत तक के अक्षर - 1 को एक मैच के लिए खोजा जाएगा।

तो आपका सिंटैक्स, a.search("cat", 0, 2) a.search("ca") बराबर है, जो पैटर्न a$ मेल खाता है।





regex