पायथन स्ट्रिंग में 3 बैकस्लैश 4 के बराबर क्यों होते हैं?


90

क्या आप बता सकते हैं कि क्यों '?\\\?'=='?\\\\?'देता है True? जो मुझे पागल कर रहा है और मुझे इसका उचित उत्तर नहीं मिल रहा है ...

>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']

8
उत्तरार्द्ध कुछ भी नहीं बच रहा है, इसलिए यह समाप्त होता है खुद को बचा लिया जाता है
— Padraic Cunningham

1
list()यहां तक ​​कि शामिल करने की आवश्यकता नहीं है :>>> '?\\\?' '?\\\\?'
— डबॉस

@PadraicCunningham यह "अंत में खुद को छोड़कर भाग जाना" नहीं है। उस समतल का क्या मतलब है?
— user253751

स्पष्ट रूप से, कारण यह है कि वे दोनों दो backslashes के बराबर हैं :-)
— RemcoGerlich

@ मिनीबिस, ठीक वैसा ही हो रहा है। क्या आप जानते हैं कि repr और str में क्या अंतर है? स्ट्रिंग में एक बैकस्लैश के साथ दोनों को प्रिंट करने की कोशिश करें और यह स्पष्ट हो सकता है
— Padraic Cunningham

जवाबों:


84

मूल रूप से, क्योंकि अजगर बैकस्लैश प्रसंस्करण में थोड़ा उदार है। Https://docs.python.org/2.0/ref/strings.html से उद्धरण :

मानक C के विपरीत, सभी अपरिचित बच क्रम को स्ट्रिंग में अपरिवर्तित छोड़ दिया जाता है, अर्थात, बैकस्लैश को स्ट्रिंग में छोड़ दिया जाता है ।

(मूल में जोर)

इसलिए, अजगर में, यह नहीं है कि तीन बैकस्लैश चार के बराबर हैं, यह है कि जब आप एक चरित्र के साथ बैकस्लैश का पालन करते हैं ?, तो दो एक साथ दो पात्रों के रूप में आते हैं, क्योंकि \?एक मान्यता प्राप्त भागने का क्रम नहीं है।


6
यह उदार के विपरीत है। उदार सबसे हर कोई है और की "यदि आप एक चरित्र है कि यह जरूरत नहीं है बैकस्लैश, बैकस्लैश कुछ नहीं करता है" के व्यवहार। साथ में एक और सम्मेलन (जो बैकस्लैशिंग अल्फ़ान्यूमेरिक्स उन्हें विशेष बना सकता है, लेकिन बैकस्लैशिंग विराम चिह्न हमेशा इसे विशेष बनाता है), आपको बहुत अच्छी प्रॉपर्टी मिलती है जिसे आप सुरक्षित रूप से बैक विस्फ़ोट करके एक स्ट्रिंग को डिफेक्ट कर सकते हैं, बिना यह जाने कि कौन से वर्ण विशेष हैं। बीच में - एक संपत्ति जो पायथन की कमी है।
— हॉब्स

24
नहीं, जब आप किसी अनजाने बैकस्लैश से बचने का उपयोग करते हैं, तो लीनियर के विपरीत एक त्रुटि बढ़ जाएगी। (जैसा कि लगभग हर संकलित भाषा करती है। याद रखें कि पायथन का स्ट्रिंग प्रसंस्करण मूल रूप से "सी की तरह है, सिवाय इसके कि हम अमान्य बैकस्लैश से बचने के बाद उसे न फोड़ें") इसके अलावा, एक स्ट्रिंग में जो भी भाषा में केवल दो अक्षर हैं जिन्हें भागने की आवश्यकता है - जो भी आप सीमांकक के रूप में उपयोग कर रहे हैं, और खुद को बैकस्लैश करें। मैं इस तर्क को नहीं समझता कि उन दोनों को याद रखना मुश्किल है।
— डैनियल मार्टिन

@DanielMartin कुछ भाषाएं हैं जहां सीमांकक कार्य करता है क्योंकि यह स्वयं का बच चरित्र है (उदाहरण के लिए 'escape''d')। आपको अन्य पात्रों को याद रखने की ज़रूरत नहीं है!
— सेतुपाय

1
ओह रुको, मुझे लगता है कि मानक पास्कल ने उस प्रणाली का भी उपयोग किया है - nyx.net/~gthompso/self_pasc.txt
— डैनियल मार्टिन

1
@DanielMartin SQL भी।
— 5

30

इसका कारण यह है कि बैकस्लैश चरित्र के लिए एक भागने चरित्र के रूप में कार्य करता है, इसके तुरंत बाद, यदि संयोजन एक मान्य भागने क्रम का प्रतिनिधित्व करता है। दर्जन या तो पलायन क्रम यहां सूचीबद्ध हैं । वे स्पष्ट शब्दों में शामिल हैं जैसे कि newline \n, क्षैतिज टैब \t, गाड़ी वापसी \rऔर अधिक अस्पष्ट जैसे कि यूनिकोड वर्णों का उपयोग करना \N{...}, जैसे \N{WAVY DASH}कि यूनिकोड वर्ण का प्रतिनिधित्व करता है \u3030। हालांकि प्रमुख बिंदु यह है कि यदि भागने का क्रम ज्ञात नहीं है, तो वर्ण क्रम को स्ट्रिंग में छोड़ दिया गया है।

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

>>> '?\\\?'
'?\\\\?'
>>> print('?\\\?')
?\\?
>>> '?\\\?' == '?\\?'    # I don't know why you think this is True???
False
>>> '?\\\?' == r'?\\?'   # but if you use a raw string for '?\\?'
True
>>> '?\\\\?' == '?\\\?'  # this is the same string... see below
True

आपके विशिष्ट उदाहरणों के लिए, पहले मामले में '?\\\?', पहला \एक बैकस्लैश छोड़ने वाले दूसरे बैकस्लैश से बच जाता है, लेकिन तीसरा बैकस्लैश बैकस्लैश के रूप में बना रहता है क्योंकि \?एक वैध एस्केप सीक्वेंस नहीं है। इसलिए जिसके परिणामस्वरूप स्ट्रिंग है ?\\?।

दूसरे मामले के लिए '?\\\\?', पहला बैकस्लैश दूसरे से बच जाता है, और तीसरा बैकस्लैश चौथे से बच जाता है जिसके परिणामस्वरूप स्ट्रिंग होती है ?\\?।

यही कारण है कि तीन backslashes चार के रूप में ही है:

>>> '?\\\?' == '?\\\\?'
True

यदि आप 3 बैकस्लैश के साथ एक स्ट्रिंग बनाना चाहते हैं, तो आप प्रत्येक बैकस्लैश से बच सकते हैं:

>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?

या आपको "कच्चे" तार अधिक समझ में आ सकते हैं:

>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?

यह स्ट्रिंग शाब्दिक के लिए एस्केप सीक्वेंस प्रोसेसिंग की ओर मुड़ता है। देखें स्ट्रिंग literals अधिक जानकारी के लिए।


आप सही हैं '?\\\?'=='?\\?'देता है False, मैं इसे गलत टाइप किया। यही कारण है कि होना चाहिए '?\\\?'=='?\\\\?'के रूप में सवाल यह संकेत करता है, मैं इसे ठीक किया गया है।
— kozooh

13

क्योंकि \xएक चरित्र स्ट्रिंग में, जब xकी तरह विशेष backslashable पात्रों में से एक नहीं है n, r, t, 0, आदि, एक बैकस्लैश और फिर एक के साथ एक स्ट्रिंग के लिए मूल्यांकन करता है x।

>>> '\?'
'\\?'

7

स्ट्रिंग शाब्दिक के तहत अजगर लेक्सिकल विश्लेषण पृष्ठ से: https://docs.python.org/2/reference/lexical_analysis.html

एक तालिका है जो सभी मान्यता प्राप्त एस्केप अनुक्रमों को सूचीबद्ध करती है।

\\ एक भागने क्रम है जो === \ है

\? भागने का क्रम नहीं है और क्या === \ _ है?

इसलिए '\\\\' '\\' है, जिसके बाद '\\' है जो '\\' है (दो बच गए)

और '\\\' '\\' है, जिसके बाद '\' भी है जो '\\' (एक बच गया और एक कच्चा) है

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

तो 'स्ट्रिंग' और "स्ट्रिंग" अजगर में सटीक एक ही बात है, वे एस्केप दृश्यों की व्याख्या को प्रभावित नहीं करते हैं।


1

शावके का उत्तर बहुत अधिक इसे कवर करता है, मैं इसे और अधिक संक्षिप्त रूप में और न्यूनतम उदाहरणों के साथ इसे पुनर्स्थापित करना चाहता हूं जो इस व्यवहार का वर्णन करते हैं।

मुझे लगता है कि जोड़ने के लिए एक बात यह है कि बचने की प्रक्रिया बाएं से दाएं चलती है, ताकि \nपहले बैकलैश का पता लगाता है और फिर भागने के लिए एक चरित्र की तलाश करता है, फिर पाता है nऔर बच निकलता है; \\nपहला बैकलैश पाता है, दूसरा पाता है और उससे बच जाता है, फिर उसे nएक शाब्दिक n के रूप में पाता और देखता है; \?बैकस्लैश पाता है और बचने के लिए एक चार की तलाश करता है, वह पाता है ?जो बच नहीं सकता है, और इसलिए \एक शाब्दिक बैकलैश के रूप में व्यवहार करता है ।

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

>>> print('\?') # \? is not a valid escape code so backslash is left as-is
\?
>>> print('\\?') # \\ is a valid escape code, resulting in a single backslash
'\?'

>>> '\?' # same as first example except that interactive interpreter escapes the backslash
\\?
>>> '\\?' # same as second example, backslash is again escaped
\\?
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.