Избегайте специальных символов HTML в Python - PullRequest
21 голосов
/ 16 января 2010

У меня есть строка, в которой могут появляться специальные символы, такие как ' или " или & (...). В строке:

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

как я могу автоматически экранировать каждый специальный символ, чтобы я получил это:

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

Ответы [ 4 ]

37 голосов
/ 16 января 2010

В Python 3.2 вы можете использовать функцию html.escape , например,

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

Для более ранних версий Python отметьте http://wiki.python.org/moin/EscapingHtml:

Модуль cgi , который поставляется с Python, имеет функцию escape() :

import cgi

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

Тем не менее, символы не выходят за пределы &, < и >. Если он используется как cgi.escape(string_to_escape, quote=True), он также экранируется ".


Вот небольшой фрагмент, который позволит вам избежать кавычек и апострофов:

 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)

Вы также можете использовать escape() из xml.sax.saxutils для выхода из html. Эта функция должна выполняться быстрее. Функция unescape() того же модуля может передавать те же аргументы для декодирования строки.

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)
5 голосов
/ 16 января 2010

Метод cgi.escape преобразует специальные символы в допустимые теги html

 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

приведет к

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

Необязательный второй параметр в cgi.бежать избегает цитаты.По умолчанию они не экранированы

4 голосов
/ 16 января 2010

Простая строковая функция сделает это:

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

Другие ответы в этой теме имеют небольшие проблемы: метод cgi.escape по какой-то причине игнорирует одинарные кавычки, и вам нужно явно попросить его сделать двойные кавычки. Связанная вики-страница выполняет все пять, но использует сущность XML &apos;, которая не является сущностью HTML.

Эта кодовая функция выполняется все пять раз, используя стандартные объекты HTML.

0 голосов
/ 23 июня 2014

Другие ответы помогут вам, например, перечисленные вами символы и некоторые другие. Однако, если вы также хотите преобразовать все остальное в имена сущностей, вам придется заняться чем-то другим. Например, если á необходимо преобразовать в &aacute;, то ни cgi.escape, ни html.escape вам там не помогут. Вы захотите сделать что-то вроде этого, используя html.entities.entitydefs, который является просто словарем. (Следующий код сделан для Python 3.x, но есть частичная попытка сделать его совместимым с 2.x, чтобы дать вам представление):

# -*- 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...