Python 정규식-R 접두사


87

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

답변:


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'프리픽스가 존재, 서열 탈출 이스케이프 시퀀스가 인식 표준 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"의 두 문자로 구성됩니다. 문자열 따옴표는 백 슬래시로 이스케이프 될 수 있지만 백 슬래시는 문자열에 남아 있습니다. 예를 들어, 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'
Massood Khaari

@MassoodKhaari이 답변을 썼을 때 출력이 정확하다고 맹세합니다.
Esteban Küber

1
8 년은 확실히 파이썬 동작의 마법적인 변화를 정당화합니다. : D
Massood Khaari

34

'r'은 다음이 "원시 문자열"임을 의미합니다. 백 슬래시 문자는 다음 문자의 특수 처리를 나타내는 대신 문자 그대로 처리됩니다.

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'를 사용하는 것이 좋습니다. 그렇지 않으면 의도하지 않은 일부 이스케이프 시퀀스를 실수로 치게 될 것입니다.
Blair Conrad

실제로 : 문자열에 백 슬래시가 포함되도록하려면 항상 원시 문자열 리터럴을 사용하십시오 (실제로 이스케이프 시퀀스를 원하는 것과는 반대로).
Thomas Wouters

@Thomas : r문자열 끝에 나타날 때 여전히 일부 시퀀스를 이스케이프합니다 : r"\"is invalid, 그렇게하려면해야 "\\"합니다. 그렇게 r"\\"하면 \\ 인쇄 된 ( "\\\\"문자열) 을 얻습니다 . 조심하세요.
Esteban Küber 2010

예, 원시 문자열 리터럴은 단일`\`로 끝날 수 없습니다.
Thomas Wouters

@ Blair / Thomas : 감사합니다-이것은 처음에 저를 혼란스럽게 만드는 일반적인 규칙이었습니다! ... 이제 모든 것이 명확 해졌습니다. 모두 감사합니다. 이 규칙을 따르면 ... 일반 텍스트 파일에서 패턴을 읽을 때 패턴이 원시 리터럴 문자열로 어떻게 전달됩니까?
JT.

0

시도해보십시오.

a = '\''
'
a = r'\''
\'
a = "\'"
'
a = r"\'"
\'

0

아래 예를 확인하십시오.

print r"123\n123" 
#outputs>>>
123\n123


print "123\n123"
#outputs>>>
123
123
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.