2011-07-29 30 views
5

Tôi muốn chuyển đổi chuỗi chứa ký tự trốn thoát đến hình thức bình thường của họ, giống như cách phân tích cú pháp từ vựng của Python thực hiện:Làm thế nào để chuyển đổi ký tự thoát trong Python?

>>> escaped_str = 'One \\\'example\\\'' 
>>> print(escaped_str) 
One \'Example\' 
>>> normal_str = normalize_str(escaped_str) 
>>> print(normal_str) 
One 'Example' 

Tất nhiên cách nhàm chán sẽ thay thế tất cả biết đến thoát nhân vật từng người một: http://docs.python.org/reference/lexical_analysis.html#string-literals

Làm cách nào để bạn triển khai normalize_str() trong mã ở trên?

+1

'chuỗi r'raw' ' – JBernardo

+2

Câu hỏi ở đây là gì? –

Trả lời

16
 
>>> escaped_str = 'One \\\'example\\\'' 
>>> print escaped_str.encode('string_escape') 
One \\\'example\\\' 
>>> print escaped_str.decode('string_escape') 
One 'example' 

Một số codec tương tự là available, chẳng hạn như ROT13 và hex.

Ở trên là Python 2.x, nhưng - vì bạn đã nói (bên dưới, trong nhận xét) rằng bạn đang sử dụng Python 3.x - trong khi nó cắt vòng để giải mã đối tượng chuỗi Unicode, nó là still possible. Các codec đã được đổi tên thành "unicode_escape" quá:

 
Python 3.3a0 (default:b6aafb20e5f5, Jul 29 2011, 05:34:11) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> escaped_str = "One \\\'example\\\'" 
>>> import codecs 
>>> print(codecs.getdecoder("unicode_escape")(escaped_str)[0]) 
One 'example' 
+1

Một lượt tốt xứng đáng khác :) Tôi đã từng thấy rằng tôi có thể giải quyết vấn đề bằng cách viết codec chuỗi của riêng tôi, FWIW. –

+1

Cách tiếp cận này dường như không hoạt động trong Python 3. Tôi nhận được: AttributeError: đối tượng 'str' không có thuộc tính 'decode'. – aligf

+1

trong python 3, 'str' là' byte' và 'unicode' là' str'. Bạn có thể cần phải đầu tiên 'mã hóa' thành utf8 hoặc ascii (để có được các byte) sau đó giải mã từ 'string_escape' – SingleNegationElimination

0

Dấu gạch chéo ngược không được ghép nối chỉ là các tạo phẩm của biểu diễn và không được lưu trữ thực sự trong nội bộ. Bạn có thể gây ra lỗi nếu cố thực hiện việc này theo cách thủ công.

Nếu quan tâm duy nhất của bạn là loại bỏ một dấu gạch chéo không trước bằng một số tiền lẻ của gạch chéo ngược, bạn có thể thử một vòng lặp while:

escaped_str = 'One \\\'example\\\'' 
chars = [] 
i = 0 
while i < len(escaped_str): 
    if i == '\\': 
     chars.append(escaped_str[i+1]) 
     i += 2 
    else: 
     chars.append(escaped_str[i]) 
     i += 1 
fixed_str = ''.join(chars) 
print fixed_str 

Kiểm tra các biến của bạn sau đó và bạn sẽ thấy lý do tại sao những gì bạn đang cố gắng để làm không có ý nghĩa.

... Nhưng trên một mặt lưu ý, tôi gần như chắc chắn 100% "giống như cách phân tích cú pháp từ vựng của Python" hiện nó không sử dụng một trình phân tích cú pháp, để nói. Trình phân tích cú pháp dành cho ngữ pháp, mô tả cách bạn kết hợp các từ với nhau.

Bạn đang nghĩ về xác minh nội dung từ vựng có thể, thường được chỉ định bằng cách sử dụng cụm từ thông dụng. Phân tích cú pháp là một con thú hoàn toàn khó khăn hơn và mạnh mẽ hơn, và không phải cái gì bạn muốn gây rối với mục đích thao tác chuỗi tuyến tính.

+2

Những gì OP gọi là "trình phân tích cú pháp từ vựng" có thể chính xác hơn được gọi là ** lexer **, mà Python chắc chắn có. May mắn thay, chúng ta không phải phát minh lại nó; nó được phản ánh trong một số chi tiết - xem câu trả lời của tôi. –

5

Tôi giả sử các câu hỏi thực sự là:

I have a string that is formatted as if it were a part of Python source code. How can I safely interpret it so that \n within the string is transformed into a newline, quotation marks are expected on either end, etc. ?

Hãy thử ast.literal_eval.

>>> import ast 
>>> print ast.literal_eval(raw_input()) 
"hi, mom.\n This is a \"weird\" string, isn't it?" 
hi, mom. 
This is a "weird" string, isn't it? 

Để so sánh, đi theo cách khác:

>>> print repr(raw_input()) 
"hi, mom.\n This is a \"weird\" string, isn't it?" 
'"hi, mom.\\n This is a \\"weird\\" string, isn\'t it?"' 
+3

literal_eval yêu cầu một chuỗi ký tự hợp lệ, bao gồm cả dấu ngoặc kép bắt đầu/kết thúc. Thêm dấu ngoặc kép (mẫu trong câu hỏi không có chúng) có nhiều trường hợp cạnh, tùy thuộc vào loại đầu vào bạn muốn chấp nhận. –

+1

@Fred rất đúng; nhưng tôi tưởng tượng rằng trong hầu hết các tình huống mà đây thực sự là vấn đề bạn muốn giải quyết, các dấu ngoặc kép bắt đầu/kết thúc thực sự ở đó, ngay cả khi OP để chúng ra khỏi ví dụ. :) –

+1

Tôi không chắc đó thực sự là vấn đề bạn luôn muốn giải quyết: tôi đoán codec string_escape (như trong câu trả lời của tôi) tồn tại để lấp đầy nhu cầu thực sự của việc chuyển đổi thoát mà không có chuỗi ký tự. (Chỉ ra literal_eval vẫn hữu ích mặc dù; tôi là upvote.;) –

0

SingleNegationElimination đã đề cập điều này, nhưng đây là một ví dụ:

Trong Python 3:

>>>escaped_str = 'One \\\'example\\\'' 
>>>print(escaped_str.encode('ascii', 'ignore').decode('unicode_escape')) 
One 'example' 
Các vấn đề liên quan