Замена текста в файле .nfo - PullRequest
       40

Замена текста в файле .nfo

0 голосов
/ 23 октября 2019

У меня есть файл colors.nfo, в котором я хочу заменить переменные и получить новый сгенерированный nfo-файл без потери шаблона.

Есть признаки ascii, с которыми я не знаю, как обращаться. Каждый раз, когда я загружаю файл file.open, заменяю переменные и записываю его в новый файл, появляются странные признаки, и шаблон уничтожается.

Вот изображение файла: https://i.imgur.com/8lqqXpg.png

Вот загруженный файл для обработки: Нажмите, чтобы загрузить - Надеюсь, все в порядке. в противном случае я буду удалять!

Надеюсь, вы понимаете проблему. Хотите заменить "% REPLACE1%", "% REPLACE2%" и "% REPLACE3%", например, "BLACKGREY", "REDWHITE" ....

  • Попытался загрузить его встрока с f.open
  • после того, как я заменил ее на string.replace ("% REPLACE1", "BLACKGREY")
  • после того, как я напишу новый файл с f.write
  • файл уничтожен, а знаки ascii не читаются, а шаблон не такой, как раньше

Пример кода:

replaceString = []
f = open("colors.nfo")
for line in f:
    replaceString.append(line.rstrip())
f.close()
replaceColors = "\n".join(replaceString)
print(replaceColors.replace("%REPLACE1%", "BLACKGREY"))

Вывод:

ÛÛ³    [x] Yellow      [ ] Yellow       [ ] Yellow      ³ÛÛ
ÛÛ³    [x] Pink        [ ] Pink         [ ] %REPLACE3%  ³ÛÛ
ÛÛ³    [ ] Green       [ ] green        [ ] Green       ³ÛÛ
ÛÛ³    [ ] Red         [ ] red          [ ] Red         ³ÛÛ
ÛÛ³    [ ] Blue        [ ] blue         [ ] Blue        ³ÛÛ
ÛÛ³    [ ] Black       [ ] %REPLACE2%   [ ] black       ³ÛÛ
ÛÛ³    [ ] White       [ ] white        [ ] white       ³ÛÛ
ÛÛ³    [ ] grey        [ ] grey         [ ] grey        ³ÛÛ
ÛÛ³    [ ] brown       [ ] brown        [ ] brown       ³ÛÛ
ÛÛ³    [ ] BLACKGREY  [ ] orange       [ ] orange      ³ÛÛ
ÛÛ³    [ ] purple      [ ] purple       [ ] purple      ³ÛÛ

Какдолжно быть:

██│    [x] Yellow      [ ] Yellow       [ ] Yellow      │██
██│    [x] Pink        [ ] Pink         [ ] %REPLACE3%  │██
██│    [ ] Green       [ ] green        [ ] Green       │██
██│    [ ] Red         [ ] red          [ ] Red         │██
██│    [ ] Blue        [ ] blue         [ ] Blue        │██
██│    [ ] Black       [ ] %REPLACE2%   [ ] black       │██
██│    [ ] White       [ ] white        [ ] white       │██
██│    [ ] grey        [ ] grey         [ ] grey        │██
██│    [ ] brown       [ ] brown        [ ] brown       │██
██│    [ ] BLACKGREY   [ ] orange       [ ] orange      │██
██│    [ ] purple      [ ] purple       [ ] purple      │██

Мне не нужны эти "ÛÛ" в моем новом созданном файле. Я хочу иметь «черные ящики», как на экране. Замена не проблема. Проблема заключается в структуре после загрузки файла в строку. когда я записываю эти строки в новый файл, шаблон не выглядит на показанном экране.

1 Ответ

0 голосов
/ 26 октября 2019

Здесь есть две проблемы

  1. правильное чтение и запись данных
  2. сохранение структуры

чтение и запись

Согласно Википедии , файлы .nfo этого типа кодируются текстовой кодировкой cp437. Поэтому эта кодировка должна быть указана при чтении и записи файла.

with open('colors.nfo', 'r', encoding='cp437') as f:
    ...

with open('colors.nfo', 'w', encoding='cp437') as f:
    ...

В качестве альтернативы, файл может быть открыт в двоичном режиме, и все операции выполняются с использованием байтов, а не текста.

with open('colors.nfo', 'rb') as f:
    ...

Если кодировка не указана, Python использует системное значение по умолчанию, в данном случае, вероятно, cp1252. 8-битное кодирование, такое как cp1252, может декодировать файл, но где cp437 декодирует b'\xdb' как «FULL BLOCK» (█), cp1252 декодирует его как 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' (Û), искажая данные, как видно из вопроса.

Сохранение структуры

Данные имеютФормат с фиксированной шириной, поэтому при замене текста необходимо соблюдать осторожность, чтобы строки назначения и замены имели одинаковую длину, иначе столбцы не будут правильно выровнены.

target = '%REPLACE1%'
replacement = 'BLACKGREY'

delta = len(target) - len(replacement)

padding = ' ' * abs(delta)
if delta > 0:
    replacement += padding
else:
    target += padding

Решения

Вот полный сценарий.

replacements = { 
        '%REPLACE1%': 'BLACKGREY',
        '%REPLACE2%': 'REDWHITE',
}   

with open('colors.nfo', encoding='cp437') as f:
    data = f.read()

for target, replacement in replacements.items():
    delta = len(target) - len(replacement)
    padding = ' ' * abs(delta)
    if delta > 0:
        replacement += padding
    else:
        target += padding

    data = data.replace(target, replacement)

with open('new-colors.nfo', 'w', encoding='cp437') as f:
    f.write(data)

Обработка как двоичных данных одинакова, за исключением того, что файлы открываются и закрываются в двоичном режиме, иtrings объявляются как bytes, а не str.

replacements = { 
        b'%REPLACE1%': b'BLACKGREY',
        b'%REPLACE2%': b'REDWHITE',
}   

with open('colors.nfo', 'rb') as f:
    data = f.read()

for target, replacement in replacements.items():
    delta = len(target) - len(replacement)
    padding = b' ' * abs(delta)
    if delta > 0:
        replacement += padding
    else:
        target += padding

    data = data.replace(target, replacement)

with open('new-colors.nfo', 'wb') as f:
    f.write(data)
...