Ранее принятый ответ - НЕПРАВИЛЬНО.
u'\ufffe'
не является символом.Если вы получите его в виде строки в кодировке Unicode, кто-то могучим образом набил.
Спецификация (также известная как ZERO WIDTH NO-BREAK SPACE) равна u'\ufeff'
>>> UNICODE_BOM = u'\N{ZERO WIDTH NO-BREAK SPACE}'
>>> UNICODE_BOM
u'\ufeff'
>>>
Читать this (Ctrl-F для поиска спецификации) и this и this (Ctrl-F для поиска спецификации).
Вот правильная и устойчивая к опечаткам и брейноответ:
Расшифруйте ваш ввод в unicode_str
.Затем сделайте следующее:
# If I mistype the following, it's very likely to cause a SyntaxError.
UNICODE_BOM = u'\N{ZERO WIDTH NO-BREAK SPACE}'
if unicode_str and unicode_str[0] == UNICODE_BOM:
unicode_str = unicode_str[1:]
Бонус: использование именованной константы дает вашим читателям немного больше информации о происходящем, чем набор произвольных, казалось бы, гексоглификов.
Обновление К сожалению, в стандартной библиотеке Python нет подходящей именованной константы.
Увы, модуль кодеков обеспечивает только "ловушку и заблуждение":
>>> import pprint, codecs
>>> pprint.pprint([(k, getattr(codecs, k)) for k in dir(codecs) if k.startswith('BOM')])
[('BOM', '\xff\xfe'), #### aarrgghh!! ####
('BOM32_BE', '\xfe\xff'),
('BOM32_LE', '\xff\xfe'),
('BOM64_BE', '\x00\x00\xfe\xff'),
('BOM64_LE', '\xff\xfe\x00\x00'),
('BOM_BE', '\xfe\xff'),
('BOM_LE', '\xff\xfe'),
('BOM_UTF16', '\xff\xfe'),
('BOM_UTF16_BE', '\xfe\xff'),
('BOM_UTF16_LE', '\xff\xfe'),
('BOM_UTF32', '\xff\xfe\x00\x00'),
('BOM_UTF32_BE', '\x00\x00\xfe\xff'),
('BOM_UTF32_LE', '\xff\xfe\x00\x00'),
('BOM_UTF8', '\xef\xbb\xbf')]
>>>
Обновление 2 Если вы еще не декодировали свой ввод и хотите проверить его на предмет спецификации, вам нужно проверить ДВА разных спецификаций для UTF-16 и, по крайней мере, ДВА разные спецификации для UTF-32.Если бы был только один способ, то вам бы не понадобилась спецификация, не так ли?
Здесь дословно неоправданный по моему собственному коду мой способ решения этой проблемы:
def check_for_bom(s):
bom_info = (
('\xFF\xFE\x00\x00', 4, 'UTF-32LE'),
('\x00\x00\xFE\xFF', 4, 'UTF-32BE'),
('\xEF\xBB\xBF', 3, 'UTF-8'),
('\xFF\xFE', 2, 'UTF-16LE'),
('\xFE\xFF', 2, 'UTF-16BE'),
)
for sig, siglen, enc in bom_info:
if s.startswith(sig):
return enc, siglen
return None, 0
Входные данныеs
должно быть по крайней мере первые 4 байта вашего ввода.Он возвращает кодировку, которую можно использовать для декодирования части ввода после BOM, плюс длину спецификации (если есть).
Если вы параноик, вы могли бы разрешить еще 2 (нестандарт) UTF-32, но Python не предоставляет для них кодировку, и я никогда не слышал о реальном происшествии, поэтому я не беспокоюсь.