पायथन रेगेक्स - आर उपसर्ग


87

क्या कोई समझा सकता है कि उदाहरण 1 से नीचे क्यों काम करता है, जब rउपसर्ग का उपयोग नहीं किया जाता है? मैंने सोचा कि rजब भी बच दृश्यों का उपयोग किया जाता है तो उपसर्ग का उपयोग किया जाना चाहिए। उदाहरण 2 और उदाहरण 3 इसे प्रदर्शित करते हैं।

# example 1
import re
print (re.sub('\s+', ' ', 'hello     there      there'))
# prints 'hello there there' - not expected as r prefix is not used

# example 2
import re
print (re.sub(r'(\b\w+)(\s+\1\b)+', r'\1', 'hello     there      there'))
# prints 'hello     there' - as expected as r prefix is used

# example 3
import re
print (re.sub('(\b\w+)(\s+\1\b)+', '\1', 'hello     there      there'))
# prints 'hello     there      there' - as expected as r prefix is not used

जवाबों:


86

क्योंकि \एस्केप सीक्वेंस तभी शुरू करें, जब वे वैलिड एग्जिट सीक्वेंस हों।

>>> '\n'
'\n'
>>> r'\n'
'\\n'
>>> print '\n'


>>> print r'\n'
\n
>>> '\s'
'\\s'
>>> r'\s'
'\\s'
>>> print '\s'
\s
>>> print r'\s'
\s

जब तक कोई 'r' या 'R' उपसर्ग मौजूद नहीं होता, तब तक स्ट्रींग में एस्केप सीक्वेंस की व्याख्या मानक सी द्वारा उपयोग किए गए नियमों के अनुसार की जाती है। मान्यता प्राप्त एस्केप सीक्वेंस इस प्रकार हैं:

Escape Sequence   Meaning Notes
\newline  Ignored  
\\    Backslash (\)    
\'    Single quote (')     
\"    Double quote (")     
\a    ASCII Bell (BEL)     
\b    ASCII Backspace (BS)     
\f    ASCII Formfeed (FF)  
\n    ASCII Linefeed (LF)  
\N{name}  Character named name in the Unicode database (Unicode only)  
\r    ASCII Carriage Return (CR)   
\t    ASCII Horizontal Tab (TAB)   
\uxxxx    Character with 16-bit hex value xxxx (Unicode only) 
\Uxxxxxxxx    Character with 32-bit hex value xxxxxxxx (Unicode only) 
\v    ASCII Vertical Tab (VT)  
\ooo  Character with octal value ooo
\xhh  Character with hex value hh

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

जब "r" या "R" उपसर्ग मौजूद होता है, तो बैकस्लैश के बाद वाला वर्ण बिना परिवर्तन के स्ट्रिंग में शामिल हो जाता है, और सभी बैकस्लैश स्ट्रिंग में रह जाते हैं। उदाहरण के लिए, स्ट्रिंग शाब्दिक r"\n"में दो वर्ण होते हैं: एक बैकस्लैश और एक लोअरकेस "n"। स्ट्रिंग उद्धरण एक बैकस्लैश के साथ बच सकते हैं, लेकिन बैकस्लैश स्ट्रिंग में रहता है; उदाहरण के लिए, r"\""दो अक्षरों से मिलकर एक मान्य स्ट्रिंग शाब्दिक है: एक बैकस्लैश और एक डबल उद्धरण; r"\"एक वैध स्ट्रिंग शाब्दिक नहीं है (यहां तक ​​कि एक कच्ची स्ट्रिंग एक विषम संख्या में बैकस्लैश समाप्त नहीं हो सकती है)। विशेष रूप से, एक कच्चा स्ट्रिंग एक एकल बैकस्लैश में समाप्त नहीं हो सकता है (क्योंकि बैकलैश निम्नलिखित उद्धरण वर्ण से बच जाएगा)। यह भी ध्यान दें कि एक नई रूपरेखा के बाद एक एकल बैकस्लैश की व्याख्या स्ट्रिंग के भाग के रूप में उन दो पात्रों के रूप में की जाती है,

इस अंतिम बिंदु को बेहतर ढंग से समझने के लिए:

>>> r'\'
SyntaxError: EOL while scanning string literal
>>> r'\''
"\\'"
>>> '\'
SyntaxError: EOL while scanning string literal
>>> '\''
"'"
>>> 
>>> r'\\'
'\\\\'
>>> '\\'
'\\'
>>> print r'\\'
\\
>>> print r'\'
SyntaxError: EOL while scanning string literal
>>> print '\\'
\

एक मामूली सुधार के रूप में, '\s'(जैसे r'\s') को एक मान्यता प्राप्त भागने अनुक्रम नहीं होने के '\\s'कारण भी प्रतिनिधित्व किया जाता है '\s'
मासूद खारी

@MassoodKhaari मैं शपथ लेता हूं कि जब मैंने यह उत्तर लिखा था तो आउटपुट सही था ... फिक्स्ड।
एस्टेबन कुबेर

1
8 साल निश्चित रूप से अजगर व्यवहार में जादुई परिवर्तन को सही ठहराते हैं। : डी
मसूद खारी

34

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

http://docs.python.org/reference/lexical_analysis.html#literals

इसलिए '\n' एक एकल न्यूलाइन है
और r'\n'दो अक्षर हैं - एक बैकस्लैश और अक्षर 'n'
इसे लिखने का एक और तरीका होगा '\\n'क्योंकि पहला बैकस्लैश दूसरा बच जाता है

इसे लिखने का एक समान तरीका

print (re.sub(r'(\b\w+)(\s+\1\b)+', r'\1', 'hello     there      there'))

है

print (re.sub('(\\b\\w+)(\\s+\\1\\b)+', '\\1', 'hello     there      there'))

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


5

बैकस्लैश से जुड़े सभी सीक्वेंस एस्केप सीक्वेंस नहीं हैं। \tऔर \f, उदाहरण के लिए, लेकिन \sनहीं है। एक गैर-कच्चे स्ट्रिंग शाब्दिक में, कोई भी \जो क्रम से बचने का हिस्सा नहीं है, उसे केवल दूसरे के रूप में देखा जाता है \:

>>> "\s"
'\\s'
>>> "\t"
'\t'

\b है तो उदाहरण के लिए 3 विफल रहता है, पलायन की अनुक्रम तथापि। (और हां, कुछ लोग इस व्यवहार को दुर्भाग्यपूर्ण मानते हैं।)


बिल्कुल सही। हालाँकि, @JT, मैं '\\ s' या r '\ s' का उपयोग करने की सलाह देता हूँ, या शायद आप अनजाने में कुछ एस्केप सीक्वेंस मारेंगे, जिनका आप मतलब नहीं था।
ब्लेयर कॉनराड

वास्तव में: हमेशा स्ट्रिंग स्ट्रिंग शाब्दिक का उपयोग करें जब आप चाहते हैं कि स्ट्रिंग में बैकस्लैश शामिल हो (जैसा कि वास्तव में एस्केप सीक्वेंस चाहते हैं।)
थॉमस वाउटर्स

@ थोमस: rअभी भी कुछ दृश्यों से बच जाता है जब वे स्ट्रिंग के अंत में दिखाई देते हैं: r"\"अमान्य है, जो आपको करना है "\\"। यदि आप करते हैं r"\\", तो आपको एक \\ मुद्रित ( "\\\\"स्ट्रिंग) मिलता है। उससे सावधान रहें।
एस्टेबन कुबेर

हां, कच्चे स्ट्रिंग शाब्दिक एक ही `में समाप्त नहीं हो सकते।
थॉमस वाउटर्स

@ ब्लेयर / थॉमस: धन्यवाद - यह सामान्य नियम था जिसका मैं पालन कर रहा था जो मुझे पहली बार में भ्रमित कर गया! ... अब सब स्पष्ट है, धन्यवाद सभी। हालांकि इस नियम का पालन करते हुए ... एक सादे पाठ फ़ाइल से पैटर्न को पढ़ते समय, पैटर्न को कच्चे शाब्दिक स्ट्रिंग के रूप में कैसे पारित किया जाएगा?
जेटी।


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