2015-11-07 18 views
8

मैं नियमित अभिव्यक्तियों में बैकस्लैश से उलझन में हूं। रेगेक्स के भीतर \ का एक विशेष अर्थ है, उदा। \d का मतलब दशमलव अंक है। यदि आप बैकस्लैश के सामने बैकस्लैश जोड़ते हैं तो यह विशेष अर्थ खो जाता है। regex-howto में एक पढ़ सकते हैं:पाइथन नियमित अभिव्यक्तियों में बैकस्लाश

शायद सबसे महत्वपूर्ण metacharacter बैकस्लैश, \ है। पाइथन स्ट्रिंग अक्षर के रूप में, विभिन्न विशेष अनुक्रमों को सिग्नल करने के लिए बैकस्लैश के बाद विभिन्न वर्णों का पालन किया जा सकता है। इसका उपयोग सभी मेटाएक्टैक्टर्स से बचने के लिए भी किया जाता है ताकि आप उन्हें पैटर्न में मिलान कर सकें; उदाहरण के लिए, यदि आपको [ या \ से मिलान करने की आवश्यकता है, तो आप उन्हें अपने विशेष अर्थ को हटाने के लिए बैकस्लैश से पहले कर सकते हैं: \[ या \\

तो print(re.search('\d', '\d'))None देता है क्योंकि \d किसी भी दशमलव अंकों से मेल खाता है, लेकिन \d में कोई नहीं है।

अब print(re.search('\\d', '\d')) से \d से मिलान करने की उम्मीद है लेकिन उत्तर अभी भी None है।

केवल print(re.search('\\\d', '\d')) आउटपुट <_sre.SRE_Match object; span=(0, 2), match='\\d'> के रूप में देता है।

क्या किसी के पास कोई स्पष्टीकरण है?

+0

http://stackoverflow.com/questions/24085680/why-do-backslashes-appear-twice – fghj

+0

संभावित डुप्लिकेट [regex के साथ बैकस्लैश से बच नहीं सकते?] (Https://stackoverflow.com/questions/4025482/ cant-escape-the-backslash-with-regex) – tripleee

उत्तर

8

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

यदि आप देखना चाहते हैं कि पाइथन आपकी स्ट्रिंग का विस्तार कैसे कर रहा है, तो बस स्ट्रिंग को प्रिंट करें। उदाहरण के लिए:

s = 'a\\b\tc' 
print s 

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

एक बार जब आप जानते हैं कि आपकी स्ट्रिंग को एन्कोड किया गया है, तो आप इसके बारे में सोच सकते हैं कि re मॉड्यूल इसके साथ क्या करेगा। उदाहरण के लिए, यदि आप स्ट्रिंग में \ से बचना चाहते हैं तो आप re मॉड्यूल पर जाते हैं, तो आपको \\ से re पर पास करने की आवश्यकता होगी, जिसका अर्थ है कि आपको अपने उद्धृत पायथन स्ट्रिंग में \\\\ का उपयोग करना होगा। पायथन स्ट्रिंग \\ के साथ समाप्त हो जाएगी और re मॉड्यूल इसे एक शाब्दिक \ वर्ण के रूप में पेश करेगा।

पाइथन स्ट्रिंग्स में \ वर्णों को शामिल करने का एक वैकल्पिक तरीका कच्चे तारों का उपयोग करना है, उदा। r'a\b'"a\\b" के बराबर है।

+0

सभी उत्तरों के लिए बहुत बहुत धन्यवाद। मुझे आर '...' के बारे में पता था और फिर भी दस्तावेज के माध्यम से चला गया लेकिन मुझे बिंदु नहीं मिला। अब चीजें बेहतर हैं। '\ b' पायथन दुभाषिया के लिए विशेष है क्योंकि इसे '\' मिलता है। '\\ b' एक '\ b' स्ट्रिंग के साथ समाप्त होने वाले अजगर दुभाषिया की व्याख्या को खत्म करता है। यह पुनः मॉड्यूल द्वारा दशमलव अंक के लिए शॉर्टकट होने के लिए पहचाना जाता है। '\\\ b' फिर भी मॉड्यूल की व्याख्या को खत्म करता है और हम स्ट्रिंग '\ b' के साथ समाप्त होते हैं। – tobmei05

+0

धन्यवाद! 4 बैकस्लाश, कितना अच्छा है। तो अजगर में कोई शाब्दिक तार नहीं हैं? मेरा मतलब PHP में है, उदाहरण के लिए, यदि आप सिंगल कोट्स का उपयोग करते हैं तो कोई प्रतिस्थापन नहीं किया जाता है। – Rolf

3

पायथन का स्वयं का स्ट्रिंग पार्सिंग (आंशिक रूप से) आपके रास्ते में आता है।

आप क्या re देखता है देखने के लिए चाहते हैं, प्रकार

print '\d' 
print '\\d' 
print '\\\d' 

अजगर कमांड प्रॉम्प्ट पर। आप देखते हैं कि \d और \\d दोनों परिणाम \d में हैं, बाद वाले को पायथन स्ट्रिंग पार्सर द्वारा देखभाल की जा रही है।

आप इन के साथ किसी भी परेशानी से बचने के लिए चाहते हैं, कच्चे तार का उपयोग के रूप में द्वारा re module documentation सुझाव: r'\\d'\\d आरई मॉड्यूल के द्वारा देखा का परिणाम देगा।

+2

https://docs.python.org/2/library/re.html '\' सेक्शन – Alex

+1

@Alex धन्यवाद, उत्तर के लिंक को जोड़ा गया। – glglgl

4

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

पुन: मॉड्यूल की खोज विधि से पहले तारों को संसाधित करने से पहले, पाइथन दुभाषिया स्ट्रिंग पर प्रारंभिक पास लेता है। यदि स्ट्रिंग में बैकस्लाश मौजूद हैं, तो पाइथन दुभाषिया को यह तय करना होगा कि प्रत्येक पाइथन एस्केप अनुक्रम (उदा। \ N या \ t) का हिस्सा है या नहीं।

नोट: इस बिंदु पर पाइथन परवाह नहीं है कि नियमित रूप से अभिव्यक्ति मेटा-कैरेक्टर है या नहीं।

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

निम्नलिखित पर विचार करें।

>>> s = '\t' 
>>> print ("[" + s + "]") 
>>> [  ]   // an actual tab character after preprocessing 

>>> s = '\d' 
>>> print ("[" + s + "]") 
>>> [\d]    // '\d' after preprocessing 

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

>>> s = '\\t' 
>>> print ("[" + s + "]") 
>>> [\t]    // '\t' after preprocessing 

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

अब '\' एक नियमित नियमित अभिव्यक्ति मेटा-कैरेक्टर भी है और इसे एक संयुक्त के रूप में व्याख्या किया जाता है, जब उस समय से खोज() विधि निष्पादित की जाती है।

निम्नलिखित कॉल पर विचार करें।

>>> match = re.search('a\\t','a\\t')  //Match is None 

यहां, मैच कोई नहीं है। क्यूं कर? पाइथन दुभाषिया अपना पास करने के बाद तारों को देखने दें।

String 1: 'a\t' 
String 2: 'a\t' 

तो मैच किसी के बराबर क्यों नहीं है?जब खोज() स्ट्रिंग 1 का व्याख्या करती है, क्योंकि यह एक नियमित अभिव्यक्ति है, बैकस्लैश को मेटा-कैरेक्टर के रूप में व्याख्या किया जाता है, न कि सामान्य चरित्र। स्ट्रिंग 2 में बैकस्लैश नियमित अभिव्यक्ति में नहीं है और इसे पहले ही पाइथन दुभाषिया द्वारा संसाधित किया गया है, इसलिए इसे सामान्य चरित्र के रूप में व्याख्या किया जाता है।

तो खोज() विधि स्ट्रिंग 'ए \ टी' में 'एस्केप-टी' की तलाश में है जो एक मैच नहीं है।

इसे ठीक करने के लिए हम खोज() विधि को मेटा-कैरेक्टर के रूप में '\' की व्याख्या नहीं करने के लिए बता सकते हैं। हम इसे से बचकर ऐसा कर सकते हैं।

निम्नलिखित कॉल पर विचार करें।

>>> match = re.search('a\\\\t','a\\t')   // Match contains 'a\t' 

फिर, पाइथन दुभाषिया के पास होने के बाद तारों को देखने दें।

String 1: 'a\\t' 
String 2: 'a\t' 

अब जब खोज() विधि नियमित अभिव्यक्ति संसाधित करता है, यह देखता है कि दूसरे बैकस्लैश पहले से बच रहा है और एक मेटा-चरित्र नहीं माना जाना चाहिए। इसलिए यह स्ट्रिंग को 'ए \ टी' के रूप में व्याख्या करता है, जो स्ट्रिंग 2 से मेल खाता है।

खोज के लिए वैकल्पिक तरीका है() एक चरित्र के रूप में '\' को नियमित अभिव्यक्ति से पहले आर को रखना है। यह पायथन दुभाषिया को स्ट्रिंग को प्रीप्रोसेस नहीं करने के लिए कहता है।

इस पर विचार करें।

>>> match = re.search(r'a\\t','a\\t')   // match contains 'a\t' 

यहां पाइथन दुभाषिया पहली स्ट्रिंग को संशोधित नहीं करता है लेकिन दूसरी स्ट्रिंग को संसाधित करता है। तार खोज करने के लिए पारित कर दिया() कर रहे हैं:

String 1: 'a\\t' 
String 2: 'a\t' 

पिछले उदाहरण में के रूप में, खोज की व्याख्या एकल वर्ण '\' और नहीं एक मेटा-चरित्र के रूप में '\', इस प्रकार स्ट्रिंग 2.

से मेल खाता है
संबंधित मुद्दे