Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 17, 2013 11:40:11

evgen34
Зарегистрирован: 2013-03-26
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Всем привет! Подскажите, пожалуйста, чем можно разрешить ситуацию: имеется файл, часть данных в нем содержится в кодировке UTF-16LE, другая часть вообще не текст. Части с текстом в нужной мне кодировке разбросаны по файлу без объявления начала и конца таких блоков. Есть ли в 3 питоне такое средство, чтобы декодировать только известные кодировке байты? Перебирать файл по 4 байта бессмысленно, так как позиции начала этих блоков не всегда кратны четырем. Пусть даже будет мусор, мне не важно.
Спасибо.

Офлайн

#2 Апрель 17, 2013 12:36:01

alexbadaloff
От: Иваново
Зарегистрирован: 2013-04-11
Сообщения: 198
Репутация: +  16  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Если кириллицы нет, можно как вариант посимвольно проверять и отсеивать не ascii:

>>> def is_ascii(s):
    return all(ord(c) < 128 for c in s)
>>> is_ascii('ô')
False
>>> is_ascii('t')
True
>>> is_ascii('в')
False



————————–
Истина где-то рядом

Офлайн

#3 Апрель 17, 2013 13:26:31

alexbadaloff
От: Иваново
Зарегистрирован: 2013-04-11
Сообщения: 198
Репутация: +  16  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Еще можно так:

import string
def isAscii(s):
    if s in string.ascii_letters or s in string.digits or s in string.punctuation:
        return True
    return False
for line in open('Connect.txt' , encoding='utf-16le'):
    st = ''
    for x in line:
        if isAscii(x):
            st += x
    print(st)

Пример файла из недавней темы приложил. Кириллица тоже тут не катит.



————————–
Истина где-то рядом

Отредактировано alexbadaloff (Апрель 17, 2013 13:36:21)

Прикреплённый файлы:
attachment Connect.txt (392 байта)

Офлайн

#4 Апрель 17, 2013 13:39:32

evgen34
Зарегистрирован: 2013-03-26
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Спасибо, alexbadaloff. Эх, а мне нужна кириллица

Офлайн

#5 Апрель 17, 2013 14:16:56

alexbadaloff
От: Иваново
Зарегистрирован: 2013-04-11
Сообщения: 198
Репутация: +  16  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

evgen34
Спасибо, alexbadaloff. Эх, а мне нужна кириллица

Вот. Если нужна utf-16le кодировка и кириллица:
import string
def is_ascii(s):
    if (ord(s) > 31 and ord(s)<122 )or(ord(s) > 1039 and ord(s) < 1104):
        return True
    return False
for line in open('test.txt', encoding='utf-16le'):
    st = ''
    for x in line:
        if is_ascii(x):
            st += x
    print(st)

Если оно, подкинь репутации. А то как-то грустно у меня с этим.



————————–
Истина где-то рядом

Отредактировано alexbadaloff (Апрель 17, 2013 14:43:31)

Офлайн

#6 Апрель 17, 2013 14:46:22

evgen34
Зарегистрирован: 2013-03-26
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

alexbadaloff
import string
def is_ascii(s):
    if (ord(s) > 31 and ord(s)<122 )or(ord(s) > 1039 and ord(s) < 1104):
        return True
    return False
for line in open('test.txt', encoding='utf-16le'):
    st = ''
    for x in line:
        if is_ascii(x):
            st += x
    print(st)
Такой вариант тоже не работает:
UnicodeDecodeError: 'utf16' codec can't decode bytes in position 1362-1363: illegal UTF-16 surrogate

Офлайн

#7 Апрель 17, 2013 14:51:38

alexbadaloff
От: Иваново
Зарегистрирован: 2013-04-11
Сообщения: 198
Репутация: +  16  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Тогда ждём более опытных.



————————–
Истина где-то рядом

Офлайн

#8 Апрель 17, 2013 14:51:53

evgen34
Зарегистрирован: 2013-03-26
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

Заметил, что блоки с текстом начинаются с четных байтов Получилось извлечь первые читабельные тексты.

ffc = open(file,"rb"); data = ffc.read(); ffc.close
text = str()
i = 0
for x in range(int(len(data)/2)):
try:
     text += data[i:i+2].decode('UTF-16LE')
     i += 2
except: i += 2
print(text)
alexbadaloff, благодарю за помощь.

Офлайн

#9 Апрель 17, 2013 17:19:16

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

При декодировании из байтов или при конструировании строки, можно передать параметр errors, который по умолчанию = ‘strict’, т.е. при любой ошибке вызывается исключение, но есть и другие.
http://docs.python.org/3.3/library/stdtypes.html#bytes.decode

>>> print(str(b'test\xfftest', 'utf-8'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 4: invalid
start byte
 
>>> print(str(b'test\xfftest', 'utf-8', 'ignore'))
testtest

Офлайн

#10 Апрель 17, 2013 22:51:49

evgen34
Зарегистрирован: 2013-03-26
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как декодировать только известные кодировке байты

reclosedev, спасибо!
В итоге получился такой код:

def is_ascii(s):
    if (ord(s) > 31 and ord(s)<122 )or(ord(s) > 1039 and ord(s) < 1104)or(ord(s) in (9,10,13)):
        return True
    return False
file = open('in.some',"rb"); data = file.read(); file.close()
text = str()
texttemp = data.decode('UTF-16LE', 'ignore')
    for i in texttemp:
        if is_ascii(i) == True:
            text += i
file = open('out.txt',"wb"); data = file.write(text.encode()); file.close()
На выходе получается текстовый файлик, в котором не так много мусора, разобраться можно

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version