Извлечь текст из двоичного файла (используя Python 2.7 в Windows 7) - PullRequest
1 голос
/ 27 декабря 2011

У меня есть двоичный файл размером около 5 МБ .., который содержит много вкрапленного текста .. и управляющих символов ..

На самом деле это эквивалент файла Outlook PST для приложения SITATEX (из SITA).

Файл содержит все текстовые сообщения, отправленные и полученные в и из внешнего мира ... (но текст должен быть извлечен с помощью двоичных управляющих символов) .. все текстовые сообщения четко доступны ... с окончанием строки ^ M символов ... и т. Д.

например: предположим, что ^ @ ^ X являются управляющими символами ... \ xaa с HEX aa и т. Д. Загружает их вокруг моего требуемого извлечения текста.

^@^@^@^@^@^@^@^@^@^@^@BLLBBCC^X^X^X^X^X^X^X^X^X
^X^X^X
MVT^M
EA1123 TEXT TEXT TEXT^M
END^M
\xaa^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
 ^@^@^@^@^@^@^@^@^@^@^@TTBBTT^X^X^X^X^X^X^X^X^X
   ^X^X^X blah blah blah... of control characters.. and then the message comes..
   MVT MESSAGE 2
   ED1123
   etc.

и т. Д. Для нескольких сообщений.

Используя Perl .. это легко сделать:

while (<>) {
  use regular expression to split messages
  m/   /


}

Как можно легко сделать это на питоне ..

  1. Как прочитать файл? двоичные и текстовые вкрапления
  2. Устранить ненужные управляющие символы
  3. парсинг сообщений между двумя \ xaa ПОЛЕЗНАЯ ТЕКСТОВАЯ ИНФОРМАЦИЯ \ xaa (HEX 'aa')
  4. распечатайте необходимые данные
  5. Перебрать все строки .. и другие файлы.

В примере текстового файла ... Мне интересно посмотреть ... BLLBBCC ... и MVT, EA1123 и т. Д.

Пожалуйста, помогите ... Если это будет очень сложно в Python ... Мне придется продумать логику в самом Perl ... так как он (Perl) не выдает много ошибок, по крайней мере, для меня циклическая часть двоичного и текстового материала .. и регулярное выражение.

Спасибо.

Обновление 02 Января после прочтения ваших ответов / комментариев

После просмотра комментариев С. Лотта и других ... Это то, где я нахожусь ... и это работает на 80% нормально.

import fileinput
import sys
import re

strfile = r'C:\Users\' \
          r'\Learn\python\mvt\sitatex_test.msgs'

f = open(strfile, 'rb')

contents = f.read() # read whole file in contents

#extract the string between two \xaaU.. multiline pattern match
#with look ahead assertion
#and this is stored in a list with all msgs
msgs = re.findall(r'\xaaU.*?(?=\xaaU)', contents, re.I|re.DOTALL|re.M)

for msg in msgs:
    #loop through msgs.. to find the first msg then next and so on.
    print "## NEW MESSAGE STARTS HERE ##"

    #for each msg split the lines.. to read line by line
    # stored as list in msglines
    msglines = msg.splitlines()
    line = 0
#then process each msgline with a message
for msgline in msglines:
    line += 1
    #msgline = re.sub(r'[\x00]+', r' ', msgline)
    mystr = msgline
    print mystr
    textstrings = re.findall(r'[\x00\x20-\x7E]+', msgline)

Пока все хорошо ... все же я еще не закончил .. потому что мне нужно проанализировать текст построчно и слово за словом ... чтобы подобрать (в качестве примера) адрес источника и заголовки, строку темы, сообщение body ... путем анализа сообщения через управляющие символы.

Теперь я застрял с ... как печатать построчно с контрольными символами, преобразованными в \x00\x02.. и т. Д. (Используя формат \xHH) ... но оставьте только обычный читаемый текст.

Например .. скажем, у меня есть это: предположим, ^@ и ^X некоторые контрольные символы line1 = '^@UG^@^@^@^@^@^@^@^@^@^@BLLBBCC^X^X^X^X^X^X^X^X^X' (в первой строке).

Когда я печатаю строку, как она есть на IDLE .. print line1 .. она печатает, скажем, только первые 2 или 3 символа ... и игнорирует остальные из-за засорения контрольных символов.

Однако, когда я печатаю с этим: print re.findall(r'.*', line1)

['\xaaUG\x02\x05\x00\x04\x00\x00\x00\x05\x00\x00\x00....
x00\x00\x00..BLLBBCC\x00\x00N\x00N\\x00
 002 010 180000 DEC 11', '']

Хорошо печатается со всеми управляющими символами, конвертированными в формат \ xHH ... и неповрежденным текстом ascii ... (так, как я этого хочу) ... с одним уловом ... в списке есть два элемента ... с "" в конец.

  1. Чем объясняется пустая строка в конце?
  2. Как этого избежать ... Я просто хочу, чтобы строка была красиво преобразована в строку (а не в список). то есть одну строку двоичного файла / текста, который нужно преобразовать в строку с кодами \ xHH ... оставьте только текст ASCII.

Использует re.findall(r'.*', line1) - это единственное простое решение ... сделать это преобразование ... или есть какой-либо другой простой метод ... преобразовать '\x00string' в \ xHH и TEXT (где это печатный символ или пробел ).

Также ... любые другие полезные комментарии, чтобы красиво вывести строки.

Спасибо.

Обновление 2 января 2011 г. - Часть 2

Я обнаружил, что re.findall(r'.+', line1) переходит в

['\xaaUG\x02\x05\x00\x04\x00\x00\x00\x05\x00\x00\x00....
    x00\x00\x00..BLLBBCC\x00\x00N\x00N\\x00
     002 010 180000 DEC 11']

без лишних пустых элементов в списке. Этот вывод после многочисленных проб и ошибок.

И все же мне понадобится помощь, чтобы полностью исключить список, но вернуть только строку. как это:

'\xaaUG\x02\x05\x00\x04..BLLBBCC..002 010 180000 DEC 11'

Добавлена ​​информация о 05 января:

@ Джон Мачин

1) \ xaaU - это разделитель между сообщениями .. В примере .. Возможно, я только что пропустил в примерах. Пожалуйста, смотрите ниже одно действительное сообщение, которое заканчивается на \ xaaU (но опущено). Следующий текст получен из repr (сообщение между r'\xaaU.*?(?=\xaaU)')

Я пытаюсь понять двоичный формат ... это типичное сообщение, которое отправляется первым, "JJJOWXH" - это адрес отправителя ... все, что следует, что имеет 7 буквенно-цифровых, - это адреса получателя. На основе отправителяадрес ... Я могу знать, является ли это 'SND' или 'RCV' .., поскольку источником является 'JJJOWXH' ... Это сообщение является 'SND', поскольку мы 'JJJOWXH'.

сообщение адресовано: JJJKLXH .... JJJKRXH .... и т. д.

Как только все .. \ x00000000 заканчивается .. заголовок sita и тема запускаются В этом конкретном случае ..."\x00QN\x00HX\x00180001 \x00" это заголовок .. и меня интересуют только все вещи между \ x00.

и тело идет следующим ... после последнего \ x00 или любого другого управляющего символа ... В этом случае... это:

COR \ r \ nMVT \ r \ nHX9136 / 17.BLNZ.JJJ \ r \ nAD2309 / 2314 EA0128 BBB \ r \ nDLRA / CI / 0032/0022 \ r\ nSI EET 02:14 HRS \ r \ n RA / 0032 ИЗ-ЗА ПОЗДНЕГО КАРТЫ ARVL \ r \ n CI / 0022 ВЫГРУЗИТЬ ПЕРЕКЛЮЧАТЕЛЬНЫЙ ПОДДОН ИЗ-ЗА НЕДОСТАТОЧНОЙ УПАКОВКИ, ВЕДУЩЕЙ К \ r \ n ПРОБЛЕМЕ С ПРОСТРАНСТВОМ

как только читаемый текст заканчивается ... первый управляющий символ, который появляется до конца \ xaaU, должен игнорироваться ... В вышеприведенных случаях .. "ПРОБЛЕМА ПРОБЕЛ" ... является последней.... затем запускаются управляющие символы ... так что их следует игнорировать ... иногда управляющих символов нет до следующего \ xaaU.

Это одно полное сообщение.

"\ xaaU \ X1C \ x04 \ x02 \ x00 \ x05 \ x06 \ x1f \ x00 \ x19 \ x00 \ x00 \ x00 \ XC4 \ x9d \ xedN \ x1a \ x00? \ x02 \ x02 \ x00B \ x02 \ x02 \ x00E \x02 \ X07 \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00M \ x02 \ XEC \ x00 \ XFF \ XFF \ x00 \ x00 \ x00 \ x00? \ x02M\ x02 \ XEC \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00 \ XFF \ XFF \ x00 \ x00: \ x03 \x10 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x7f \ x00JJJOWXH \x00 \ x05w \ x01x \ x01 \ x00 \ x01JJJKLXH \ x00 \ x00 \ x7f \ x01 \ x80 \ x01 \ x00 \ x01JJJKRXH \ x00F \ x87 \ x01 \ x88 \ x01 \ x00 \ x01JJJFFXH \ x00 \ XFF \ x8f \ x01 \x90 \ x01 \ x00 \ x01JJJFCXH \ x00 \ XFF \ x97 \ x01 \ x98 \ x01 \ x00 \ x01JJJFAXH \ x00 \ x00 \ x9f \ x01 \ xa0 \ x01 \ x00 \ x01JJJKPXH \ x00 \ x00 \ xa7 \ x01 \ xa8 \x01 \ x00 \ x01HAKUOHU \ x00 \ x00 \ XAF \ x01 \ XB0 \ x01 \ x00 \ x01BBBHRXH \ x00 \ x00 \ xb7 \ x01 \ XB8 \ x01 \ x00 \ x01BBBFFHX \ x00 \ x00 \ XBF \ x01 \ xc0 \ x01 \x00 \ x01BBBOMHX \ x00 \ x00 \ xc7 \ x01 \ xc8 \ x01 \ x00 \ x01BBBFMXH \ x00 \ x00 \ XCF \ x01 \ xd0 \ x01 \ x00 \ x01JJJHBER \ x00 \ x00 \ xd7 \ x01 \ xd8 \ x01 \ x00 \x01BBBFRUO \ x00 \ x00 \ XDF \ x01 \ xe0 \ x01 \ x00 \ x01BBBKKHX \ x00 \ x00 \ xe7 \ x01 \ X Е8 \ x01 \ x00 \ x01JJJLOTG \ x00 \ x01 \ ХеР \ x01 \ xf0 \ x01 \ x00 \ x01JJJLCTG \x00 \ x00 \ xf7 \ x01 \ XF8 \ x01 \ x00 \ x01HDQOMTG \ X005 \ XFF \ x01 \ x00 \ x02 \ x00 \ x01CHACSHX \ x00K \ X07 \ x02 \ x08 \ x02 \ x00 \ x01JJJKZXH \ x00F \ X0F \ x02 \x10 \ x02 \ x00 \ x01BBBOMUO \ x00 \ x17 \ x02 \ x18 \ x02 \ x00 \ x01BBBORXH \ x00 \ x1f \ x02 \ x02 \ x00 \ x01BBBOPXH \ x00W '\ x02 (\ x02 \ x00 \ x01CHACSHX \ x00 / \ x020 \ x02 \ x00 \ x01JJJDBXH \ x0007 \ x028 \ x02 \ x000100000000 x000000000000000000000000\ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000\ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x00000000 \ x00 \ x000000000000000000000000000000\ nMVT \ r \ nHX9136 / 17.BLNZ.JJJ \ r \ nAD2309 / 2314 EA0128 BBB \ r \ nDLRA / CI / 0032/0022 \ r \ nSI EET 02:14 HRS \ r \ n RA / 0032 из-за поздней декларацииACFT \ r \ n CI / 0022 ЗАГРУЗИТЬ ПЕРЕКРЫТИЕ ПАЛЕТЫ ИЗ-ЗА НЕУДАЧНОЙ УПАКОВКИ, ВЕДУЩЕЙ К ПРОБЛЕМЕ \ r \ n ПРОСТРАНСТВА \ x00D- \ xedN \ x00 \ x04 \ x1a \ x00t <\ x93 \ x01x \ x00M_ \ x00 "</p>

2) Я больше не использую. + После того, как 'repr' известен.

3) каждое сообщение является многострочным ... и мне нужно сохранить все управляющие символы, чтобы понять смысл этого проприетарного формата ... вот почему мне нужно было repr, чтобы увидеть его поближе.объясняет ... Это всего 1 сообщение из 1000 с файлом ... и некоторые из них - "SND", а некоторые - "RCV" ... и для "RCV" не будет "000000" .. и иногдаЕсть небольшие исключения из правила ... но обычно это нормально.

Любые дальнейшие предложения кто-нибудь ... Я все еще работаю с файлом ... чтобы восстановить текст без изменений ... с отправителем и получателемадреса.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

Python также поддерживает регулярные выражения. Я не говорю на Perl, поэтому я не знаю точно, что делает ваш Perl-код, но эта программа на Python может вам помочь:

import re
with open('yourfile.pst') as f:
    contents = f.read()
textstrings = re.findall(r'[\x20-\x7E]+', contents)

Это даст вам список всех строк одного или нескольких печатных символов ASCII в файле. Это может быть не совсем то, что вы хотите, но вы можете настроить его оттуда.

Обратите внимание, что если вы используете Python 3, вам нужно беспокоиться о различии между двоичными и текстовыми данными, и это становится немного сложнее. Я предполагаю, что вы в Python 2.

2 голосов
/ 27 декабря 2011

В: Как прочитать файл?двоичный файл и текст с вкраплениями

A: Не беспокойтесь, просто прочитайте его как обычный текст, и вы сможете сохранить свою двоичную / текстовую дихотомию (иначе вы не сможетедля регулярного регулярного выражения)

fh = open('/path/to/my/file.ext', 'r')
fh.read()

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

fh = open('/path/to/my/file.ext', 'rb')

В: Исключить ненужные управляющие символы

A: Использовать модуль python re .Ваш следующий вопрос задайте как

В: разберите сообщения между двумя \ xaa ПОЛЕЗНАЯ ИНФОРМАЦИЯ О ТЕКСТЕ \ xaa (HEX 'aa')

A: модуль re имеет функцию findall, которая работает так, как вы ожидаете (в основном).

import re

mytext = '\xaaUseful text that I want to keep\xaa^X^X^X\xaaOther text i like\xaa'
usefultext = re.findall('\xaa([a-zA-Z^!-~0-9 ]+)\xaa', mytext)

Q: распечатайте необходимые данные

*A: Есть функция печати ...

print usefultext

Q: Перебрать все строки ... и другие файлы.

fh = open('/some/file.ext','r')

for lines in fh.readlines():
    #do stuff

Я позволюВы выясните модуль os , чтобы выяснить, какие файлы существуют / как их перебирать.

1 голос
/ 02 января 2012

Вы говорите:

И все же мне понадобится помощь, чтобы полностью исключить список, но вернуть только строку. как это

Другими словами, у вас есть foo = [some_string], и вы делаете print foo, что в качестве стороны делает repr(some_string), но заключает его в квадратные скобки, которые вам не нужны. Так что просто сделайте print repr(foo[0]).

Кажется, есть несколько необъяснимых вещей:

  1. Вы говорите, что полезный текст заключен в квадратные скобки \xaaU, но в примере файла вместо двух вхождений этого разделителя в начале есть только \xaa (отсутствует U) и больше ничего. 1020 *

  2. Вы говорите

    Я обнаружил, что re.findall (r '. +', Line1) переходит в ...

    Это фактически удаляет \n (но не \r !!) - я думал, что разрывы строк стоит сохранить при попытке восстановить сообщение электронной почты.

    >>> re.findall(r'.+', 'abc\r\ndef\r\n\r\n')
    ['abc\r', 'def\r', '\r']
    

    Что вы сделали с \r символами? Вы проверяли многострочное сообщение? Вы проверяли файл с несколькими сообщениями?

  3. Осталось угадать, кто или что предназначен для потребления вашей продукции; ты пишешь

    Мне нужно разобрать текст построчно и слово за словом

    но вы, кажется, слишком озабочены тем, чтобы напечатать сообщение "разборчиво", например \xab вместо тарабарщины.

  4. Похоже, что последние 6 или около того строк в вашем последнем коде (for msgline in msglines: и т. Д.) Должны иметь отступ на один уровень.

Можно ли уточнить все вышеперечисленное?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...