バックスラッシュでエスケープされた文字列をエスケープ解除する方法は?


100

別の文字列をバックスラッシュでエスケープしたバージョンの文字列があるとします。Pythonで文字列をエスケープ解除する簡単な方法はありますか?たとえば、次のことができます。

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

ただし、これには、セキュリティ上のリスクがある(おそらく信頼できない)文字列をeval()に渡す必要があります。文字列を受け取り、セキュリティに影響を与えずに文字列を生成する関数が標準libにありますか?

回答:


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

9
Python 3と互換性のあるものはありますか?
thejinx0r 2015

3
@ thejinx0r:こっちを見て:stackoverflow.com/questions/14820429/...
ChristopheD

29
基本的にPython3に必要なものprint(b"Hello,\nworld!".decode('unicode_escape'))
ChristopheD

3
Python 3の場合value.encode('utf-8').decode('unicode_escape')
Casey Kuball

8
警告: value.encode('utf-8').decode('unicode_escape') 文字列内の非ASCII文字が破損しています。入力にASCII文字のみが含まれることが保証されていない限り、これは有効な解決策ではありません。
Alex Peters

34

ast.literal_eval安全に使用できます:

式ノードまたはPython式を含む文字列を安全に評価します。提供される文字列またはノードは、文字列、数値、タプル、リスト、辞書、ブール値、およびなしのPythonリテラル構造のみで構成されます。(終わり)

このような:

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

3
文字列にセミコロンをエスケープすると、このコードが壊れます。構文エラー「行継続文字の後の予期しない文字」を
スローする

3
@darksky予告astライブラリーは、二重引用符(いずれかが必要です"'、でも、"""あるいは'''実際にPythonコードとして実行しようとしているが、セキュリティ(防止列注射を)強化されているので、あなたのescaped_str周り)を
InQβ

@ no1xsyzy:OPの場合はすでにどちらかです。これが正解であるstrであるreprstrか、bytesOPの場合のようにオブジェクトが。unicode-escapeコーデック答えはそうでないときのためですreprが、エスケープ文字(文字列データ自体の一部として引用符で囲まれていない)他の何らかの形態。
ShadowRanger 2018

utf-8文字では、これは機能しません。コードパッケージで最後の回答をチェックアウトします。実際に機能します。
rubmz

20

与えられたすべての答えは、一般的なUnicode文字列で壊れます。以下は、私が知る限り、すべての場合においてPython3で機能します。

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

コメントで概説されているように、次のようにモジュールliteral_evalからメソッドを使用することもできます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))

ただし、入力文字列が区切り文字として二重引用符または単一引用符のどちらを使用しているかが不明な場合、または文字列が適切にエスケープされていると想定できない場合は、encode / decodeメソッドが引き続き機能する間にliteral_evala が発生することがありますSyntaxError


ast.literal_eval('"mon€y\\nröcks"') == "mon€y\nröcks"Python 3.7.3でうまく動作します
oldrinb

コメント@oldrinbをありがとう!私はそれを含めるために答えを編集しました。
JeskoHüttenhain

14

Python 3では、strオブジェクトにはdecodeメソッドがなく、オブジェクトを使用する必要がありbytesます。ChristopheDの回答はpython 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"

2
、それを一緒に置きますvalue.encode('utf-8').decode('unicode_escape')
Casey Kuball

6
文字列にUTF-8の非ASCII文字(つまり、ポーランド文字)が含まれている場合、これは悲しいことに壊れます
Pax0r

への呼び出しで洗練に適したエンコーディングを選択してみましたencodeか?
asac

utf-8文字では、これは機能しません。コードパッケージで最後の回答をチェックアウトします。実際に機能します。
rubmz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.