Быстрый способ фильтрации незаконных символов xml unicode в python?

Спецификация XML содержит список символов Unicode, которые либо незаконны, либо «обескуражены». Учитывая строку, как я могу удалить из нее все незаконные символы?

Я придумал следующее регулярное выражение, но это немного глоток.

illegal_xml_re = re.compile(u'[\x00-\x08\x0b-\x1f\x7f-\x84\x86-\x9f\ud800-\udfff\ufdd0-\ufddf\ufffe-\uffff]') clean = illegal_xml_re.sub('', dirty) 

(Python 2.5 не знает о символах Unicode выше 0xFFFF, поэтому нет необходимости их фильтровать).

2 Solutions collect form web for “Быстрый способ фильтрации незаконных символов xml unicode в python?”

Недавно мы ( сопровождающие Trac XmlRpcPlugin ) были уведомлены о том, что регулярное выражение выше разделяет суррогатные пары на узких строках Python (см . Комментарий: 13: билет: 11050 ). Альтернативный подход состоит в использовании следующего регулярного выражения (см. Th: changeset: 13729 ).

 _illegal_unichrs = [(0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F), (0x7F, 0x84), (0x86, 0x9F), (0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF)] if sys.maxunicode >= 0x10000: # not narrow build _illegal_unichrs.extend([(0x1FFFE, 0x1FFFF), (0x2FFFE, 0x2FFFF), (0x3FFFE, 0x3FFFF), (0x4FFFE, 0x4FFFF), (0x5FFFE, 0x5FFFF), (0x6FFFE, 0x6FFFF), (0x7FFFE, 0x7FFFF), (0x8FFFE, 0x8FFFF), (0x9FFFE, 0x9FFFF), (0xAFFFE, 0xAFFFF), (0xBFFFE, 0xBFFFF), (0xCFFFE, 0xCFFFF), (0xDFFFE, 0xDFFFF), (0xEFFFE, 0xEFFFF), (0xFFFFE, 0xFFFFF), (0x10FFFE, 0x10FFFF)]) _illegal_ranges = ["%s-%s" % (unichr(low), unichr(high)) for (low, high) in _illegal_unichrs] _illegal_xml_chars_RE = re.compile(u'[%s]' % u''.join(_illegal_ranges)) 

ps См. это сообщение о суррогатах, объясняющих, для чего они предназначены.

Обновите, чтобы не соответствовать (заменить) 0x0D который является допустимым символом XML .

Вы также можете использовать метод перевода unicode для удаления выбранных кодовых точек. Однако сопоставление, которое у вас есть, довольно большое (2128 кодовых точек), и это может сделать его намного медленнее, чем просто использование регулярного выражения:

 ranges = [(0, 8), (0xb, 0x1f), (0x7f, 0x84), (0x86, 0x9f), (0xd800, 0xdfff), (0xfdd0, 0xfddf), (0xfffe, 0xffff)] # fromkeys creates the wanted (codepoint -> None) mapping nukemap = dict.fromkeys(r for start, end in ranges for r in range(start, end+1)) clean = dirty.translate(nukemap) 
  • Черри и XML-данные из нескольких файлов
  • есть ли что-нибудь, чтобы преобразовать xml -> yaml напрямую?
  • Как включить пространства имен в xml-файл с помощью lxml?
  • python: экранирование символов не-ascii в XML
  • Как открыть этот XML-файл для создания dataframe в Python?
  • Python: какая библиотека синтаксического анализа XML будет работать из-за коробки для Python 2.4 и выше?
  • Использование Python и lxml для проверки XML на внешний DTD
  • Как загрузить одного-много детей на событие onchange?
  • Python - лучший язык программирования в мире.