Подтвердить что ты не робот

Исключить специальные символы HTML в Python

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

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

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

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

Ответ 1

В 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)

Ответ 2

Метод cgi.escape преобразует специальные charecters в действительные теги 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.escape ускоряет кавычки. По умолчанию они не экранируются

Ответ 3

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

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

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

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

Ответ 4

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