Я пытаюсь создать инструмент для очистки имен пользователей из файлов журнала Minecraft. В них есть много символов раздела, потому что это то, что игра использует для форматирования цветов, и я хочу удалить их и следующий символ из каждой строки файла. Однако, когда я пытаюсь прочитать файл с Ruby, я не могу получить нужный символ. Чтобы попытаться понять это, я проверил множество файлов, содержащих знак раздела разными способами. Файлы: a.log
, b.log
и c.log
.Почему символ раздела (§) не читается правильно в зависимости от того, где он был создан?
a.log
был созданecho
ИНГ§
в файлb.log
был созданcat
ИНГАМИ один из моих собственных логов Minecraft, а затем удалить все другие символы в Vimc.log
был создан в блокноте
Когда я смотрю на них в блокноте, все они будут правильно отображаться:
Это то же самое, когда я смотрю на них все в Vim:
Тогда вещи начинают стать странным Я открываю их в Ruby. Вот код, который я использовал:
a = File.open("./a.log")
aa = a.read
puts aa.encoding
puts aa.ord
puts aa
b = File.open("./b.log")
bb = b.read
puts bb.encoding
puts bb.ord
puts bb
c = File.open("./c.log")
cc = c.read
puts cc.encoding
puts cc.ord
puts cc
А вот выход:
IBM437
239
§
IBM437
167
▒
IBM437
167
▒
Я подумал, что, возможно, это был просто Руби быть странным, пока я не использовал cat
, чтобы отобразить содержимое каждого файла:
$ cat a.log b.log c.log
§
▒
▒
Это не имеет никакого смысла, потому что кодировка была показана одинаковой. Поэтому я решил открыть каждый файл в шестнадцатеричном зрителя (HxD):
Что !? Все они содержат один и тот же символ. Единственное различие между тем, которое работает, и теми, что нет, EF BB BF C2
в a.log
! Почему это имеет значение, и как я могу исправить это, чтобы он работал с Ruby's gsub
?
(Я попытался сделать это, используя кучу вещей, которые я нашел в Интернете с String.force_encoding
и String.encode
, но не получил нигде, кроме как начать видеть градусные символы на выходе. Если вы можете привести пример который работает для всех трех типов журнальных файлов, я был бы очень признателен.)
EDIT: Я немного поиграл и нашел, что это необходимо для байта C2
. UTF-8 использует 0xC2 0xA7
, а UTF-16 использует 0x00A7
. Что я могу сделать для правильной конвертации (и почему у Notepad и Vim нет какой-либо проблемы, отображающей ее как знак раздела?)
Какую версию Ruby вы используете (<2.0)? Возможно, вас заинтересует [Byte Order Mark] (https://en.wikipedia.org/wiki/Byte_order_mark). – spickermann
@spickermann 'ruby 2.3.1p112 (версия 2016-04-26 54768) [i386-mingw32]' – Peril