Учитывая вариант использования Django, существует два ответа на это. Вот django.utils.html.escape
функция для ссылки:
def escape(html):
"""Returns the given HTML with ampersands, quotes and carets encoded."""
return mark_safe(force_unicode(html).replace('&', '&').replace('<', '&l
t;').replace('>', '>').replace('"', '"').replace("'", '''))
Для инвертирования это, функция Гепарда, описанная в ответе Jake's, должно работать, но пропускает одинарную кавычку. Эта версия включает обновленный кортеж с порядком замены, инвертированной для предотвращения симметричных проблем:
def html_decode(s):
"""
Returns the ASCII decoded version of the given HTML string. This does
NOT remove normal HTML tags like <p>.
"""
htmlCodes = (
("'", '''),
('"', '"'),
('>', '>'),
('<', '<'),
('&', '&')
)
for code in htmlCodes:
s = s.replace(code[1], code[0])
return s
unescaped = html_decode(my_string)
Это, однако, не является общим решением; это только подходит для строк, закодированных django.utils.html.escape
. В более общем плане это - хорошая идея придерживаться стандартной библиотеки:
# Python 2.x:
import HTMLParser
html_parser = HTMLParser.HTMLParser()
unescaped = html_parser.unescape(my_string)
# Python 3.x:
import html.parser
html_parser = html.parser.HTMLParser()
unescaped = html_parser.unescape(my_string)
# >= Python 3.5:
from html import unescape
unescaped = unescape(my_string)
Как предложение: может иметь больше смысла хранить HTML, незавершенный в Вашей базе данных. Стоило бы изучить возвращение незавершенных результатов от BeautifulSoup, если это возможно, и предотвращения этого процесса в целом.
С Django, выходя только происходит во время шаблонного рендеринга; таким образом для предотвращения выхода из Вас просто говорят механизму шаблонной обработки не выходить из Вашей строки. Чтобы сделать это, используйте одну из этих опций в Вашем шаблоне:
{{ context_var|safe }}
{% autoescape off %}
{{ context_var }}
{% endautoescape %}
Я нашел это в исходном коде Гепарда ( здесь )
htmlCodes = [
['&', '&'],
['<', '<'],
['>', '>'],
['"', '"'],
]
htmlCodesReversed = htmlCodes[:]
htmlCodesReversed.reverse()
def htmlDecode(s, codes=htmlCodesReversed):
""" Returns the ASCII decoded version of the given HTML string. This does
NOT remove normal HTML tags like <p>. It is the inverse of htmlEncode()."""
for code in codes:
s = s.replace(code[1], code[0])
return s
не уверенным, почему они инвертируют список, я думаю, что это имеет отношение к способу, которым они кодируют, таким образом, с Вами это, возможно, не должно быть инвертировано. Также на вашем месте я изменил бы htmlCodes, чтобы быть списком кортежей, а не списком списков..., это входит в мою библиотеку хотя:)
я заметил, что Ваш заголовок, который попросили относительно, кодирует также, таким образом, вот Гепард, кодируют функцию.
def htmlEncode(s, codes=htmlCodes):
""" Returns the HTML encoded version of the given string. This is useful to
display a plain ASCII text string on a web page."""
for code in codes:
s = s.replace(code[0], code[1])
return s
Посмотрите у основания этого страница в Python wiki, существует по крайней мере 2 опции "не выйти" из HTML.
Используйте решение daniel, если набор закодированных символов относительно ограничивается. Иначе пользуйтесь одной из многочисленных анализирующих HTML библиотек.
мне нравится BeautifulSoup, потому что он может обработать уродливый XML/HTML:
http://www.crummy.com/software/BeautifulSoup/
для Вашего вопроса, существует пример в их документация
from BeautifulSoup import BeautifulStoneSoup
BeautifulStoneSoup("Sacré bleu!",
convertEntities=BeautifulStoneSoup.HTML_ENTITIES).contents[0]
# u'Sacr\xe9 bleu!'
Для кодирования HTML, существует cgi.escape из стандартной библиотеки:
>> help(cgi.escape)
cgi.escape = escape(s, quote=None)
Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true, the quotation mark character (")
is also translated.
Для декодирования HTML, я использую следующее:
import re
from htmlentitydefs import name2codepoint
# for some reason, python 2.5.2 doesn't have this one (apostrophe)
name2codepoint['#39'] = 39
def unescape(s):
"unescape HTML code refs; c.f. http://wiki.python.org/moin/EscapingHtml"
return re.sub('&(%s);' % '|'.join(name2codepoint),
lambda m: unichr(name2codepoint[m.group(1)]), s)
Для чего-либо более сложного, я использую BeautifulSoup.
Комментарий Даниэля в качестве ответа:
«Экранирование происходит в Django только во время рендеринга шаблона. Следовательно, в этом нет необходимости - вы просто указываете движку шаблонов не ускользать. { {context_var | safe}} или {% autoescape off%} {{context_var}} {% endautoescape%} "
Я нашел прекрасную функцию по адресу: http://snippets.dzone.com/posts/show/4569
def decodeHtmlentities(string):
import re
entity_re = re.compile("&(#?)(\d{1,5}|\w{1,8});")
def substitute_entity(match):
from htmlentitydefs import name2codepoint as n2cp
ent = match.group(2)
if match.group(1) == "#":
return unichr(int(ent))
else:
cp = n2cp.get(ent)
if cp:
return unichr(cp)
else:
return match.group()
return entity_re.subn(substitute_entity, string)[0]