2010-01-16 22 views
18

Ich habe eine Zeichenfolge, in der Sonderzeichen wie ' oder " oder & (...) erscheinen können. In der Zeichenkette:Escape spezielle HTML-Zeichen in Python

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

wie kann ich automatisch jedes Sonderzeichen entkommen, so dass ich diese:

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

Antwort

33

in Python 3.2, könnten Sie die html.escape function verwenden, z.B.

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

Für frühere Versionen von Python, überprüfen http://wiki.python.org/moin/EscapingHtml:

Die cgi module, die mit Python kommt ein escape() function hat:

import cgi 

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

Es ist jedoch nicht Zeichen über & zu entkommen, < und >. Wenn es als cgi.escape(string_to_escape, quote=True) verwendet wird, entgeht es auch ".


Hier ist ein kleiner Ausschnitt, den Sie zitiert und Apostrophe auch entkommen lassen:

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) 

Sie auch html entkommen können escape() from xml.sax.saxutils. Diese Funktion sollte schneller ausgeführt werden. Der unescape()-Funktion des gleichen Moduls können die gleichen Argumente übergeben werden, um eine Zeichenfolge zu dekodieren.

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

Danke für 'quote = true' in' cgi. Escape – sidx

+0

Beachten Sie, dass einige Ihrer Ersetzungen nicht HTML-kompatibel sind. Zum Beispiel: https://www.w3.org/TR/xhtml1/#C_16 Anstelle von ', verwenden Sie ' Ich denke, ein paar andere wurden zum HTML4-Standard hinzugefügt, aber das war nicht. – leetNightshade

5

Die cgi.escape Methode konvertieren spezielle charecters auf gültige HTML-Tags

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 

führt in

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

Der optionale zweite Paramter auf cgi.escape Anführungszeichen entkommt. Standardmäßig sind sie es nicht

entkam
+1

Ich verstehe nicht, warum cgi.escape ist so zimperlich über die Konvertierung von Zitaten, und ignoriert einzelne Anführungszeichen vollständig. –

+1

Da Anführungszeichen in PCDATA nicht maskiert werden müssen, müssen sie in Attributen maskiert werden (die häufig Trennzeichen mit doppelten Anführungszeichen verwenden), und der erste Fall ist weitaus häufiger als der zweite. Im Allgemeinen ist es eine Lehrbuch 90% Lösung (mehr wie> 99%). Wenn Sie jedes letzte Byte speichern müssen und dynamisch herausfinden möchten, um welche Art von Quotierung es sich handelt, verwenden Sie 'xml.sax.saxutils.quoteattr()'. –

4

Eine einfache String-Funktion tun:

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

Andere Antworten zu diesem Thema haben kleinere Probleme: Die cgi.escape Methode aus irgendeinem Grunde ignoriert Apostrophe, und Sie müssen Sie explizit darum bitten, doppelte Anführungszeichen zu verwenden. Die Wiki-Seite verknüpft alle fünf, aber verwendet die XML-Entität &apos;, die keine HTML-Entität ist.

Diese Code-Funktion macht alle fünf die ganze Zeit, mit HTML-Standard-Entities.

0

Die anderen Antworten hier helfen Ihnen mit den aufgelisteten Charakteren und ein paar anderen. Wenn Sie jedoch auch alles andere in Entitätsnamen konvertieren möchten, müssen Sie etwas anderes tun. Zum Beispiel, wenn á in &aacute; konvertiert werden muss, wird weder cgi.escape noch html.escape Ihnen dort helfen.Sie möchten etwas tun, das html.entities.entitydefs verwendet, das nur ein Wörterbuch ist. (Der folgende Code wird für Python 3.x gemacht, aber es gibt ein Teil-Versuch es kompatibel mit 2.x zu machen, um Ihnen eine Vorstellung zu geben):

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