बैकस्लैश-एस्कैप्ड स्ट्रिंग को अन-एस्केप कैसे करें?


100

मान लीजिए कि मेरे पास एक स्ट्रिंग है जो एक अन्य स्ट्रिंग का बैकस्लैश-एस्केप संस्करण है। वहाँ एक आसान तरीका है, पायथन में, स्ट्रिंग को हटाने के लिए? उदाहरण के लिए, मैं कर सकता था:

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

हालाँकि इसमें एक (संभवतः अविश्वसनीय रूप से) स्ट्रिंग को शामिल करना शामिल है जो कि eval () के लिए है जो एक सुरक्षा जोखिम है। क्या मानक लिब में एक फ़ंक्शन है जो एक स्ट्रिंग लेता है और बिना सुरक्षा निहितार्थ के एक स्ट्रिंग का उत्पादन करता है?

जवाबों:


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

9
क्या कुछ ऐसा है जो अजगर 3 के साथ संगत है?
thejinx0r

3
@ thejinx0r: यहाँ पर एक नज़र है: stackoverflow.com/questions/14820429/…
ChristopheD

29
मूल रूप से Python3 के लिए आप चाहते हैंprint(b"Hello,\nworld!".decode('unicode_escape'))
ChristopheD

3
अजगर 3 के लिए, उपयोगvalue.encode('utf-8').decode('unicode_escape')
केसी कुबैल

8
चेतावनी: value.encode('utf-8').decode('unicode_escape') स्ट्रिंग में गैर-ASCII वर्णों को भ्रष्ट करता है । जब तक इनपुट की गारंटी केवल ASCII वर्णों के लिए होती है, यह एक वैध समाधान नहीं है।
एलेक्स पीटर्स

35

आप उपयोग कर सकते हैं ast.literal_evalजो सुरक्षित है:

सुरक्षित रूप से एक अभिव्यक्ति नोड या एक पायथन अभिव्यक्ति युक्त स्ट्रिंग का मूल्यांकन करें। प्रदान की गई स्ट्रिंग या नोड में केवल निम्नलिखित पायथन शाब्दिक संरचनाएं शामिल हो सकती हैं: स्ट्रिंग्स, संख्याएं, ट्यूपल्स, सूचियां, डीकट्स, बुलियन और कोई नहीं। (समाप्त)

ऐशे ही:

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

3
स्ट्रिंग में एक बचा हुआ अर्ध-बृहदान्त्र होने से यह कोड टूट जाता है। एक वाक्यविन्यास त्रुटि "लाइन निरंतरता चरित्र के बाद अप्रत्याशित चरित्र" फेंकता है
अंधेरे

3
@darksky सूचना है कि astपुस्तकालय (या तो उद्धरण की आवश्यकता है "या ', यहां तक कि """या ''', अपने escaped_str के आसपास) के बाद से यह वास्तव में अजगर कोड लेकिन बढ़ाता सुरक्षा (रोकता स्ट्रिंग इंजेक्शन) के रूप में इसे चलाने के लिए कोशिश कर रहा है
InQβ

@ no1xsyzy: ओपी के मामले में जो पहले से ही मामला है; इस सही जवाब जब है strएक है reprएक की strया bytesओ पी के मामले में के रूप में वस्तु; unicode-escapeकोडेक जवाब जब यह नहीं एक है के लिए है repr, लेकिन बच गए पाठ का एक अन्य स्वरूप (स्ट्रिंग डेटा खुद के हिस्से के रूप उद्धरण से घिरा हुआ नहीं)।
शैडो रेंजर

utf-8 chars के साथ यह काम नहीं करेगा। कोड पैकेज के साथ अंतिम उत्तर चेकआउट करें। यह वास्तव में काम करता है।
रबज

FWIW मैं कुछ बच गए JSON पाठ को पार्स करने का प्रयास कर रहा था और यह त्रुटि प्राप्त करता रहा [ERROR] TypeError: string indices must be integersऔर इस समाधान ने इसे हल करने के लिए काम किया। स्ट्रिंग को अनस्केप करें, फिर JSON के रूप में पार्स करें।
साइबर-भिक्षु

20

सभी दिए गए उत्तर सामान्य यूनिकोड स्ट्रिंग्स पर टूटेंगे। जहां तक ​​मैं बता सकता हूं, सभी मामलों में पायथन 3 के लिए निम्नलिखित काम करता है:

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

हालाँकि, यदि आप अनिश्चित हैं कि इनपुट स्ट्रिंग डबल या सिंगल कोट्स को सीमांकक के रूप में उपयोग करता है, या जब आप यह नहीं मान सकते कि यह ठीक से बच गया है, तो literal_evalकुछ SyntaxErrorसमय के लिए एन्कोड / डीकोड विधि अभी भी काम कर सकती है।


ast.literal_eval('"mon€y\\nröcks"') == "mon€y\nröcks"मेरे लिए ठीक काम करता है Python 3.7.3 के साथ
पुराने

टिप्पणी के लिए धन्यवाद @oldrinb! मैंने इसमें शामिल होने के उत्तर को संपादित किया।
जेसको हुटनथिन

14

अजगर 3 में, strऑब्जेक्ट में एक decodeविधि नहीं है और आपको एक bytesऑब्जेक्ट का उपयोग करना होगा । क्रिस्टोफडी का जवाब अजगर 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')
केसी कुबैल

6
यह दुख की बात है अगर स्ट्रिंग कुछ utf-8 गैर- ascii अक्षर (यानी पॉलिश अक्षर) शामिल होंगे
Pax0r

क्या आपने कॉल में पॉलिश के लिए उपयुक्त एन्कोडिंग चुनने की कोशिश की है encode?
asac

utf-8 chars के साथ यह काम नहीं करेगा। कोड पैकेज के साथ अंतिम उत्तर चेकआउट करें। यह वास्तव में काम करता है।
रबज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.