Python에서 노드의 이스케이프 시퀀스 처리
파일이나 사용자로부터 입력을 공용면 이스케이프 시퀀스가 포함 된 암호화를 얻습니다. 이스케이프 시퀀스 리터럴에서 이스케이프 시퀀스를 처리하는 것과 같은 방식으로 이스케이프 시퀀스를 처리하고 싶습니다 .
예를 들어 myString
다음과 같이 정의 가정 해 보겠습니다 .
>>> myString = "spam\\neggs"
>>> print(myString)
spam\neggs
나는 수행하는 함수를 원한다 process
.
>>> print(process(myString))
spam
eggs
함수가 Python의 모든 이스케이프 시퀀스를 처리 할 수 있어야합니다 (위 링크의 표에 다음 됨).
어디에서 수행하는 기능이 있습니까?
올바른 방법은 '문자열 이스케이프'코드를 사용하여 사용하여 사용하는 것입니다.
>>> myString = "spam\\neggs"
>>> decoded_string = bytes(myString, "utf-8").decode("unicode_escape") # python3
>>> decoded_string = myString.decode('string_escape') # python2
>>> print(decoded_string)
spam
eggs
AST 또는 eval을 사용하지 않습니다. 보다 많은 코덱을 사용하는 것이 안전합니다.
unicode_escape
일반적으로 작동하지 않습니다.
밝혀 그것은 string_escape
또는 unicode_escape
특히, 실제 유니 코드의 존재에 일을 하지 않습니다 - 솔루션은 일반적으로 작동하지 않습니다.
ASCII가 아닌 모든 문자가 이스케이프 된다고 확신 할 수있는 권한 (그리고 처음 128 개 초과하는 모든 문자는 ASCII가 아닙니다) unicode_escape
입니다. 그러나 이미 ASCII가 아닌 문자가 있으면 문제가 발생합니다.
unicode_escape
기본적으로 바이트를 유니 코드 텍스트로 변환하도록 설계했습니다. 그러나 많은 곳에서 (예 : Python 소스 코드) 소스 데이터는 이미 유니 코드 텍스트입니다.
첫번째 방법은 텍스트를 바이트로 인코딩하는 것입니다. UTF-8은 모든 텍스트에 실행하라는 메시지가 표시됩니다.
다음 예제는 Python 3에 있기 때문에 그렇다고 리터럴이 더 깨끗하지만 Python 2와 3 모두에서 약간 다른 표현으로 존재합니다.
>>> s = 'naïve \\t test'
>>> print(s.encode('utf-8').decode('unicode_escape'))
naïve test
글쎄, 그건 틀렸어.
텍스트를 텍스트로 사용하는 코덱을 사용하는 새로운 권장 방법은 codecs.decode
직접 호출 하는 것입니다. 도움이 되나요?
>>> import codecs
>>> print(codecs.decode(s, 'unicode_escape'))
naïve test
아뇨. (또한 위는 Python 2의 UnicodeError입니다.)
unicode_escape
코덱은, 그 이름에도 불구하고 모든 비 ASCII 바이트 라틴 -1 (ISO-8859-1) 인코딩에 가정하는 것이 검증되었습니다. 따라서 다음과 같이해야합니다.
>>> print(s.encode('latin-1').decode('unicode_escape'))
naïve test
그러나 그것은 끔찍합니다. 이것은 마치 유니 코드가 전혀 발명되지 않은 것처럼 256 개의 Latin-1 문자로 제한됩니다!
>>> print('Ernő \\t Rubik'.encode('latin-1').decode('unicode_escape'))
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0151'
in position 3: ordinal not in range(256)
문제를 해결하기 위해 정규식 추가
(놀랍게도 두 가지 문제가 없습니다.)
우리가해야 할 일은 unicode_escape
우리가 ASCII 텍스트라고 확신하는 것들 에만 디코더를 적용하는 것입니다. 특히 ASCII 텍스트로 보장되는 유효한 Python 이스케이프 시퀀스에만 적용 할 수 있습니다.
계획은 정규 표현식을 사용하여 이스케이프 시퀀스를 찾고, re.sub
이스케이프되지 않은 값으로 대체 하기 위해 함수를 인수로 사용하는 것입니다.
import re
import codecs
ESCAPE_SEQUENCE_RE = re.compile(r'''
( \\U........ # 8-digit hex escapes
| \\u.... # 4-digit hex escapes
| \\x.. # 2-digit hex escapes
| \\[0-7]{1,3} # Octal escapes
| \\N\{[^}]+\} # Unicode characters by name
| \\[\\'"abfnrtv] # Single-character escapes
)''', re.UNICODE | re.VERBOSE)
def decode_escapes(s):
def decode_match(match):
return codecs.decode(match.group(0), 'unicode-escape')
return ESCAPE_SEQUENCE_RE.sub(decode_match, s)
그리고 그것으로 :
>>> print(decode_escapes('Ernő \\t Rubik'))
Ernő Rubik
파이썬 3에 대한 실제로 정확하고 편리한 대답 :
>>> import codecs
>>> myString = "spam\\neggs"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
spam
eggs
>>> myString = "naïve \\t test"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
naïve test
에 관한 세부 사항 codecs.escape_decode
:
codecs.escape_decode
바이트 단위 디코더입니다.codecs.escape_decode
b"\\n"
->b"\n"
,b"\\xce"
-> 와 같은 ASCII 이스케이프 시퀀스를 디코딩b"\xce"
합니다.codecs.escape_decode
는 바이트 객체의 인코딩에 대해 신경 쓰지 않거나 알 필요가 없지만 이스케이프 된 바이트의 인코딩은 나머지 객체의 인코딩과 일치해야합니다.
배경:
- @rspeer 가 정확합니다 :
unicode_escape
python3에 대한 잘못된 솔루션입니다. 이는unicode_escape
이스케이프 된 바이트를 디코딩 한 다음 바이트를 유니 코드 문자열로 디코딩하지만 두 번째 작업에 사용할 코덱에 대한 정보를 수신하지 않기 때문입니다. - @Jerub 이 정확합니다 : AST 또는 eval을 피하십시오.
- 나는 "Python3에서 어떻게 .decode ( 'string-escape')를합니까?"에 대한이 답변
codecs.escape_decode
에서 처음 발견 했습니다. . 그 대답에서 알 수 있듯이 해당 함수는 현재 파이썬 3에 대해 문서화되지 않았습니다.
ast.literal_eval
기능은 가깝게 있지만, 문자열이 제대로 첫번째 인용 될 것으로 예상됩니다.
물론 백 슬래시 이스케이프에 대한 Python의 해석은 문자열이 인용되는 방식 ( ""
vs r""
vs u""
, 삼중 따옴표 등)에 따라 다르므로 사용자 입력을 적절한 따옴표로 묶고 literal_eval
. 따옴표로 묶으 literal_eval
면 숫자, 튜플, 사전 등이 반환 되지 않습니다 .
사용자가 문자열을 감싸려는 유형의 인용되지 않은 따옴표를 입력하면 여전히 까다로울 수 있습니다.
이것은 나쁜 방법이지만 문자열 인수로 전달 된 이스케이프 된 8 진수를 해석하려고 할 때 효과적이었습니다.
input_string = eval('b"' + sys.argv[1] + '"')
eval과 ast.literal_eval 사이에 차이가 있다는 점을 언급 할 가치가 있습니다 (eval이 훨씬 안전하지 않음). 파이썬의 eval () 대 ast.literal_eval () 사용하기를 참조하십시오 .
아래 코드는 작동해야합니다. \ n은 문자열에 표시되어야합니다.
import string
our_str = 'The String is \\n, \\n and \\n!'
new_str = string.replace(our_str, '/\\n', '/\n', 1)
print(new_str)
참고 URL : https://stackoverflow.com/questions/4020539/process-escape-sequences-in-a-string-in-python
'IT' 카테고리의 다른 글
기기의 IP 주소를 가져옵니다. (0) | 2020.09.05 |
---|---|
클래스가 클래스를 확장하고 인터페이스를 구현할 수 있습니까? (0) | 2020.09.05 |
float : left div를 가운데에 정렬? (0) | 2020.09.04 |
Android 작업 표시 줄에 오버플로가 표시되지 않음 (0) | 2020.09.04 |
Pandas 데이터 프레임에 누락 된 날짜 추가 (0) | 2020.09.04 |