Стандарт Unicode гласит , что символ \ufeff
имеет два разных значения. При начале потока данных его следует использовать как порядок следования байтов и / или кодирования, но в других местах его следует интерпретировать как неразрывный пробел нулевой ширины .
Итак, код
bom = unicode(codecs.BOM_UTF8, "utf8" )
r = r.replace(bom, '')
не просто удаляет подпись в кодировке utf-8 (она же спецификация), но и удаляет все встроенные неразрывные пробелы нулевой ширины .
В некоторых более ранних версиях python не было варианта кодека "utf-8", который пропускает спецификацию при чтении потоков данных. Поскольку это было несовместимо с другими другими кодеками Unicode, кодек "utf-8-sig" был введен с версия 2.5 , который пропускает спецификацию.
Так что, возможно, «ошибка Python», упомянутая в комментариях к коду, относится к этому.
Однако более вероятно, что «ошибка» относится к внедренным \ufeff
символам. Но поскольку в стандарте Unicode четко указано, что их можно интерпретировать как допустимые символы, потребителю данных необходимо решить, как с ними обращаться, и поэтому не ошибка в python.