2010-01-16 61 views
18

Tôi có một chuỗi có các ký tự đặc biệt như ' hoặc " hoặc & (...) có thể xuất hiện. Trong chuỗi:Thoát các ký tự HTML đặc biệt trong Python

string = """ Hello "XYZ" this 'is' a test & so on """ 

làm thế nào tôi có thể tự động thoát khỏi tất cả các ký tự đặc biệt, vì vậy mà tôi có được điều này:

string = " Hello "XYZ" this 'is' a test & so on " 

Trả lời

33

Trong Python 3.2, bạn có thể sử dụng html.escape function, ví dụ

>>> string = """ Hello "XYZ" this 'is' a test & so on """ 
>>> import html 
>>> html.escape(string) 
' Hello "XYZ" this 'is' a test & so on ' 

Đối với phiên bản trước của Python, kiểm tra http://wiki.python.org/moin/EscapingHtml:

Các cgi module mà đi kèm với Python có escape() function:

import cgi 

s = cgi.escape("""& < >""") # s = "&amp; &lt; &gt;" 

Tuy nhiên, nó không thoát khỏi nhân vật ngoài &, <>. Nếu nó được sử dụng làm cgi.escape(string_to_escape, quote=True), nó cũng sẽ thoát khỏi ".


Dưới đây là một đoạn nhỏ mà sẽ cho phép bạn thoát khỏi dấu ngoặc kép và dấu nháy cũng như:

html_escape_table = { 
    "&": "&amp;", 
    '"': "&quot;", 
    "'": "&apos;", 
    ">": "&gt;", 
    "<": "&lt;", 
    } 

def html_escape(text): 
    """Produce entities within text.""" 
    return "".join(html_escape_table.get(c,c) for c in text) 

Bạn cũng có thể sử dụng escape() from xml.sax.saxutils để thoát html. Hàm này sẽ thực thi nhanh hơn. Hàm unescape() của cùng một mô-đun có thể được chuyển cùng một đối số để giải mã một chuỗi.

from xml.sax.saxutils import escape, unescape 
# escape() and unescape() takes care of &, <and>. 
html_escape_table = { 
    '"': "&quot;", 
    "'": "&apos;" 
} 
html_unescape_table = {v:k for k, v in html_escape_table.items()} 

def html_escape(text): 
    return escape(text, html_escape_table) 

def html_unescape(text): 
    return unescape(text, html_unescape_table) 
+0

Cảm ơn bạn đã báo giá «True' trong' cgi. escape' – sidx

+0

Lưu ý, một số thay thế của bạn không tuân thủ HTML. Ví dụ: https://www.w3.org/TR/xhtml1/#C_16 Thay vì ', hãy sử dụng ' Tôi đoán một số khác đã được thêm vào tiêu chuẩn HTML4, nhưng không phải vậy. – leetNightshade

5

Phương pháp cgi.escape sẽ chuyển đổi charecters đặc biệt để các thẻ html hợp lệ

import cgi 
original_string = 'Hello "XYZ" this \'is\' a test & so on ' 
escaped_string = cgi.escape(original_string, True) 
print original_string 
print escaped_string 

sẽ dẫn đến

Hello "XYZ" this 'is' a test & so on 
Hello &quot;XYZ&quot; this 'is' a test &amp; so on 

Các paramter tùy chọn thứ hai trên cgi.escape thoát dấu ngoặc kép. Theo mặc định, họ không thoát

+1

Tôi không hiểu tại sao cgi.escape quá phức tạp về việc chuyển đổi các trích dẫn, và bỏ qua các dấu nháy đơn hoàn toàn. –

+1

Bởi vì dấu ngoặc kép không cần phải được thoát trong PCDATA, chúng * cần * được thoát trong các thuộc tính (trong đó, thường xuyên hơn không, sử dụng dấu ngoặc kép cho dấu phân tách) và trường hợp cũ phổ biến hơn so với sau. Nói chung, đó là một giải pháp 90% sách giáo khoa (giống như> 99%). Nếu bạn phải lưu từng byte cuối cùng và muốn nó tự động tìm ra loại trích dẫn nào, hãy sử dụng 'xml.sax.saxutils.quoteattr()'. –

4

Một chức năng chuỗi đơn giản sẽ làm điều đó:

def escape(t): 
    """HTML-escape the text in `t`.""" 
    return (t 
     .replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;") 
     .replace("'", "&#39;").replace('"', "&quot;") 
     ) 

câu trả lời khác trong chủ đề này có vấn đề nhỏ: Phương pháp cgi.escape vì một lý do bỏ qua đơn dấu ngoặc kép, và bạn cần phải yêu cầu nó một cách rõ ràng để làm hai dấu nháy kép. Trang wiki được liên kết thực hiện tất cả năm, nhưng sử dụng thực thể XML &apos;, đây không phải là một thực thể HTML.

Chức năng mã này thực hiện tất cả năm lần, sử dụng các thực thể chuẩn HTML.

0

Các câu trả lời khác ở đây sẽ trợ giúp như các ký tự bạn đã liệt kê và một vài người khác. Tuy nhiên, nếu bạn cũng muốn chuyển đổi mọi thứ khác thành tên thực thể, bạn sẽ phải làm một việc khác. Ví dụ: nếu á cần phải được chuyển đổi thành &aacute;, không phải cgi.escape cũng không phải html.escape sẽ giúp bạn ở đó.Bạn sẽ muốn làm một cái gì đó như thế này sử dụng html.entities.entitydefs, mà chỉ là một từ điển. (Mã sau đây được tạo cho Python 3.x, nhưng có một nỗ lực một phần để làm cho nó tương thích với 2.x để cung cấp cho bạn một ý tưởng):

# -*- coding: utf-8 -*- 

import sys 

if sys.version_info[0]>2: 
    from html.entities import entitydefs 
else: 
    from htmlentitydefs import entitydefs 

text=";\"áèïøæỳ" #This is your string variable containing the stuff you want to convert 
text=text.replace(";", "$ஸ$") #$ஸ$ is just something random the user isn't likely to have in the document. We're converting it so it doesn't convert the semi-colons in the entity name into entity names. 
text=text.replace("$ஸ$", "&semi;") #Converting semi-colons to entity names 

if sys.version_info[0]>2: #Using appropriate code for each Python version. 
    for k,v in entitydefs.items(): 
     if k not in {"semi", "amp"}: 
      text=text.replace(v, "&"+k+";") #You have to add the & and ; manually. 
else: 
    for k,v in entitydefs.iteritems(): 
     if k not in {"semi", "amp"}: 
      text=text.replace(v, "&"+k+";") #You have to add the & and ; manually. 

#The above code doesn't cover every single entity name, although I believe it covers everything in the Latin-1 character set. So, I'm manually doing some common ones I like hereafter: 
text=text.replace("ŷ", "&ycirc;") 
text=text.replace("Ŷ", "&Ycirc;") 
text=text.replace("ŵ", "&wcirc;") 
text=text.replace("Ŵ", "&Wcirc;") 
text=text.replace("ỳ", "&#7923;") 
text=text.replace("Ỳ", "&#7922;") 
text=text.replace("ẃ", "&wacute;") 
text=text.replace("Ẃ", "&Wacute;") 
text=text.replace("ẁ", "&#7809;") 
text=text.replace("Ẁ", "&#7808;") 

print(text) 
#Python 3.x outputs: &semi;&quot;&aacute;&egrave;&iuml;&oslash;&aelig;&#7923; 
#The Python 2.x version outputs the wrong stuff. So, clearly you'll have to adjust the code somehow for it. 
Các vấn đề liên quan