101

rプレフィックスが使用されていない場合に、以下の例 1 が機能する理由を誰でも説明できますか? 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
4

5 に答える 5

92

\有効なエスケープ シーケンスである場合にのみ、エスケープ シーケンスを開始するためです。

>>> '\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' プレフィックスが存在しない限り、文字列内のエスケープ シーケンスは、標準 C で使用される規則と同様の規則に従って解釈されます。認識されるエスケープ シーケンスは次のとおりです。

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" の 2 つの文字で構成されます。文字列の引用符はバックスラッシュでエスケープできますが、バックスラッシュは文字列に残ります。たとえば、r"\""バックスラッシュと二重引用符の 2 文字で構成される有効な文字列リテラルです。r"\"は有効な文字列リテラルではありません (生の文字列であっても、奇数のバックスラッシュで終わることはできません)。具体的には、生の文字列を単一のバックスラッシュで終了することはできません (バックスラッシュは次の引用文字をエスケープするため)。また、単一のバックスラッシュとそれに続く改行は、文字列の一部としてこれら 2 つの文字として解釈されることに注意してください。

この最後の点をよりよく説明するには:

>>> 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 '\\'
\
于 2010-02-11T01:24:16.987 に答える
41

「r」は、次が「生の文字列」であることを意味します。バックスラッシュ文字は、後続の文字の特別な扱いを意味する代わりに、文字どおりに扱われます。

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

'\n'単一の改行
であり、2r'\n'つの文字です。バックスラッシュと文字 'n'
別の書き方は'\\n'、最初のバックスラッシュが 2 番目のバックスラッシュをエスケープするためです。

これを書く同等の方法

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'))

Python が有効なエスケープ文字ではない文字を処理する方法のため、これらの二重バックスラッシュのすべてが必要なわけではありません。たとえば、 and'\s'=='\\s'については同じではありません。私の好みは、明示的で、すべてのバックスラッシュを 2 倍にすることです。'\b''\\b'

于 2010-02-11T01:30:11.713 に答える
6

バックスラッシュを含むすべてのシーケンスがエスケープ シーケンスであるとは限りません。\t\fは、たとえば、ありますが、そうで\sはありません。非生の文字列リテラルで\は、エスケープ シーケンスの一部ではないものは、単なる別の と見なされます\

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

\b ただし、エスケープ シーケンスであるため、例 3 は失敗します(そして、一部の人々は、この振る舞いをかなり不幸だと考えています。)

于 2010-02-11T01:24:55.320 に答える