programing

백슬래시 탈출 끈을 푸는 방법?

testmans 2023. 11. 1. 22:13
반응형

백슬래시 탈출 끈을 푸는 방법?

다른 문자열의 백슬래시 이스케이프 버전인 문자열이 있다고 가정합니다.Python에서 문자열을 쉽게 탈출할 수 있는 방법이 있습니까?예를 들면 다음과 같이 할 수 있습니다.

>>> escaped_str = '"Hello,\\nworld!"'
>>> raw_str = eval(escaped_str)
>>> print raw_str
Hello,
world!
>>> 

그러나 여기에는 보안 위험인 (신뢰할 수 없는) 문자열을 평가()에 전달해야 합니다.string을 사용하고 보안에 영향을 주지 않는 string을 생성하는 기능이 표준 lib에 있습니까?

>>> print '"Hello,\\nworld!"'.decode('string_escape')
"Hello,
world!"

사용가능ast.literal_eval안전한 위치:

식 노드 또는 Python 식이 들어 있는 문자열을 안전하게 평가합니다.제공되는 문자열 또는 노드는 문자열, 숫자, 튜플, 목록, 딕트, 부울런 및 없음(END)과 같은 Python 리터럴 구조로만 구성될 수 있습니다.

다음과 같은 경우:

>>> import ast
>>> escaped_str = '"Hello,\\nworld!"'
>>> print ast.literal_eval(escaped_str)
Hello,
world!

주어진 모든 답변은 일반 유니코드 문자열로 바뀝니다.제가 아는 한, 다음은 모든 경우에 파이썬3에서 작동합니다.

from codecs import encode, decode
sample = u'mon€y\\nröcks'
result = decode(encode(sample, 'latin-1', 'backslashreplace'), 'unicode-escape')
print(result)

최근 파이썬 버전에서는 가져오기 없이도 작동합니다.

sample = u'mon€y\\nröcks'
result = sample.encode('latin-1', 'backslashreplace').decode('unicode-escape')

obataku가 제안한 것처럼, 당신은 또한 방법을 사용할 수 있습니다.ast모듈은 다음과 같습니다.

import ast
sample = u'mon€y\\nröcks'
print(ast.literal_eval(F'"{sample}"'))

또는 문자열에 실제로 문자열 리터럴(따옴표 포함)이 포함되어 있는 경우 이와 같습니다.

import ast
sample = u'"mon€y\\nröcks"'
print(ast.literal_eval(sample))

그러나 입력 문자열이 큰따옴표 또는 작은따옴표를 구분 기호로 사용하는지 여부를 확신할 수 없는 경우 또는 입력 문자열이 적절하게 이스케이프되었다고 가정할 수 없는 경우literal_eval제기할 수도 있습니다.SyntaxError인코딩/decode 방법이 여전히 작동합니다.

파이썬 3에서.str물체는 a를 가지고 있지 않습니다.decodemethod 그리고 당신은 a를 사용해야 합니다.bytes물건.크리스토프 D의 대답은 파이썬 2를 다루고 있습니다.

# create a `bytes` object from a `str`
my_str = "Hello,\\nworld"
# (pick an encoding suitable for your str, e.g. 'latin1')
my_bytes = my_str.encode("utf-8")

# or directly
my_bytes = b"Hello,\\nworld"

print(my_bytes.decode("unicode_escape"))
# "Hello,
# world"

Python3의 경우 다음을 고려합니다.

my_string.encode('raw_unicode_escape').decode('unicode_escape')

'raw_unicode_escape' 코덱은 latin1로 인코딩되지만, 먼저 다른 모든 유니코드 코드 포인트를 이스케이프로 바꿉니다.'\uXXXX'아니면'\UXXXXXXXX'form. 중요한 점은 기존 백슬래시를 건드리지 않는다는 점에서 일반적인 'unicode_escape' 코덱과 다릅니다.

따라서 일반적인 'unicode_escape' 디코더를 적용하면 새로 이스케이프된 코드 포인트와 원래 이스케이프된 요소가 모두 동일하게 취급되며, 그 결과는 이스케이프되지 않은 네이티브 유니코드 문자열입니다.

('raw_unicode_escape' 디코더는 오직'\uXXXX'그리고.'\UXXXXXXXX'다른 모든 탈출을 무시한 폼.)

문서: https://docs.python.org/3/library/codecs.html?highlight=codecs#text-encodings

일부 백슬래시만 디코딩하도록 사용자 지정 문자열 파서 - 이 경우 escapes\"그리고.\'

def backslash_decode(src):
    "decode backslash-escapes"
    slashes = 0 # count backslashes
    dst = ""
    for loc in range(0, len(src)):
        char = src[loc]
        if char == "\\":
            slashes += 1
            if slashes == 2:
                dst += char # decode backslash
                slashes = 0
        elif slashes == 0:
            dst += char # normal char
        else: # slashes == 1
            if char == '"':
                dst += char # decode double-quote
            elif char == "'":
                dst += char # decode single-quote
            else:
                dst += "\\" + char # keep backslash-escapes like \n or \t
            slashes = 0
    return dst

src = "a" + "\\\\" + r"\'" + r'\"' + r"\n" + r"\t" + r"\x" + "z" # input
exp = "a" + "\\"   +  "'"  +  '"'  + r"\n" + r"\t" + r"\x" + "z" # expected output

res = backslash_decode(src)

print(res)
assert res == exp

언급URL : https://stackoverflow.com/questions/1885181/how-to-un-escape-a-backslash-escaped-string

반응형