2010-01-16 22 views
18

Tengo una cadena donde pueden aparecer caracteres especiales como ' o " o & (...). En la cadena:Escape de caracteres HTML especiales en Python

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

cómo puedo escapar de forma automática cada carácter especial, por lo que me sale esto:

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

Respuesta

33

En Python 3.2, se podría utilizar el html.escape function, por ejemplo,

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

Para versiones anteriores de Python, comprobar http://wiki.python.org/moin/EscapingHtml:

El cgi module que viene con Python tiene un escape() function:

import cgi 

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

Sin embargo, no escapa más allá de caracteres &, < y >. Si se usa como cgi.escape(string_to_escape, quote=True), también se escapa ".


Aquí hay un pequeño fragmento que le permitirá escapar comillas y apóstrofes así:

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) 

También puede utilizar escape() from xml.sax.saxutils escapar html. Esta función debería ejecutarse más rápido. La función unescape() del mismo módulo se puede pasar los mismos argumentos para decodificar una cadena.

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

Gracias por 'quote = TRUE en' cgi. escape' – sidx

+0

Tenga en cuenta que algunos de sus reemplazos no son compatibles con HTML. Uno por ejemplo: https://www.w3.org/TR/xhtml1/#C_16 En lugar de ', use ' Supongo que se agregaron algunos otros al estándar HTML4, pero ese no. – leetNightshade

5

El método cgi.escape convertirá charecters especiales para etiquetas HTML válido

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 

dará lugar a

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

El segundo parametro opcional en cgi.escape escapa comillas. Por defecto, no se escaparon

+1

No entiendo por qué cgi.escape es tan aprensivo con la conversión de presupuestos, e ignora por completo las comillas simples. –

+1

Debido a que las comillas no necesitan ser escapadas en PCDATA, * tienen que * escaparse en atributos (que, muy a menudo, utilizan comillas dobles para delimitadores), y el primer caso es mucho más común que el último. En general, es una solución de libro de texto al 90% (más como> 99%). Si tiene que guardar hasta el último byte y quiere que adivine dinámicamente qué tipo de cita lo hace, use 'xml.sax.saxutils.quoteattr()'. –

4

una función de cadena simple se hará hacerlo:

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

Otras respuestas en este tema tienen problemas menores: El método cgi.escape por alguna razón ignora comillas simples, y usted Necesito pedirle explícitamente que haga comillas dobles. La página wiki vinculada tiene los cinco, pero usa la entidad XML &apos;, que no es una entidad HTML.

Esta función de código hace las cinco todas las veces, utilizando entidades estándar de HTML.

0

Las otras respuestas aquí le ayudarán con, por ejemplo, los caracteres que enumeró y algunos otros. Sin embargo, si también quieres convertir todo lo demás en nombres de entidades, tendrás que hacer otra cosa. Por ejemplo, si se debe convertir á a &aacute;, ni cgi.escape ni html.escape le ayudarán allí.Querrá hacer algo como esto que use html.entities.entitydefs, que es solo un diccionario. (El siguiente código se hace para Python 3.x, pero hay un intento parcial en lo que es compatible con 2.x para darle una idea):

# -*- 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. 
Cuestiones relacionadas