У меня есть двоичный файл размером около 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/ /
}
Как можно сделать это на python легко..
В образце текстового файла... мне интересно видеть.. BLLBBCC... и MVT и EA1123 и так далее.
Пожалуйста, помогите... Если это будет очень сложно в python.. Мне придется продумать логику в perl себе.. поскольку он (perl) не бросает много ошибок у меня, по крайней мере, для цикла бинарного и текстового материала.. и регулярное выражение.
Благодарю.
Обновление 02Jan после прочтения ваших ответов/комментариев
Пройдя через комментарии С.Лотта и другие... Вот где я нахожусь.. и он работает на 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)
До сих пор так хорошо.. все-таки я не полностью готов.. потому что мне нужно разобрать текст по строкам и слово за словом.. чтобы взять (как пример) исходный адрес и заголовки, тему, тело сообщения. путем разбора сообщения через управляющие символы.
Теперь я застрял... как печатать строки за строкой с управляющими символами, преобразованными в \x00\x02..
т \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 нетронутым.. (так же, как я хочу).. с одним уловом.. список состоит из двух элементов.. с '' в конце.
Является ли использование re.findall(r'.*', line1)
единственным удобным решением.. для этого преобразования.. или есть какой-либо другой простой метод.. преобразовать '\x00string'
в \xHH и TEXT (где это печатный символ или пробел).
Также.. любые другие полезные комментарии, чтобы получить строки хорошо.
Благодарю.
Обновление 2Jan2011 - часть 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'
Добавлена информация о 05Jan:
@John Machin
1)\xaaU является разделителем между сообщениями. В примере.. Возможно, я просто оставил в выборках. Ниже приведено одно фактическое сообщение, которое заканчивается на \xaaU (но не указано). После текста получается сообщение (msg между r'\xaaU.*?(?=\xaaU)'
)
Я пытаюсь понять двоичный формат. Это типичное сообщение, которое отправляется первым "JJJOWXH" - это адрес отправителя. Все, что следует за ним, имеет 7 буквенно-цифровых адресов получателя. На основе адреса отправителя.. Я могу узнать, является ли это "SND" или "RCV".. поскольку источником является "JJJOWXH"... Этот msg является "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 DUE ПОЗДНУЮ АРВЛЕРНУЮ ПРОДУКЦИЮ CI/0022 ОТКРЫТЬ ПЕРЕГРУЗЧИК ПАДЕНИЯ В НЕПРАВИЛЬНОМ УПАКОВКЕ В ЛИДЕРЕ В ПРОСТРАНСТВЕННОЙ ПРОБЛЕМЕ
после завершения чтения прочитанного текста... первый символ управления, который появляется до конца \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\x01BBOPXH\x00W '\ x02 (\ x02\x00\x01CHACSHX\x00\x020\x02\x00\x01JJJDBXH\x0007\x028\x02\x00010000\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\x00000000\x00\x00000000\x00\x00000000\x00QN\x00HX\x00180001\x00COR\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 ПОСЛЕДУЮЩАЯ АРВТНАЯ АКФТ \r\n CI/0022 ОТКРЫТЬ ПЕРЕГРУЗЧИК ПАДЕНИЯ ВНУТРИ НЕЗАКОННОГО УПАКОВКИ TO\r\n ПРОСТРАНСТВЕННАЯ ПРОБЛЕМА \x00D-\xedN\x00\x04\x1a\x00t <\ x93\x01x\x00M_\x00 "
2) Я больше не использую. + После того, как "репрезентация" известна.
3) каждое сообщение является многострочным.. и мне нужно сохранить все контрольные символы, чтобы понять смысл этого проприетарного формата.. вот почему мне нужен реестр, чтобы увидеть его близко.
Надеюсь, это объяснит... Это всего лишь 1 сообщение из 1000 с файлом... и некоторые из них "SND", а некоторые - "RCV"... и для "RCV" не будет "000000". и иногда есть незначительные исключения из правила... но обычно это нормально.
Любые дополнительные предложения кому-либо. Я все еще работаю с файлом.., чтобы восстановить текст без изменений... с адресами отправителя и получателя.
Спасибо.
Ты говоришь:
Тем не менее мне понадобится помощь, чтобы полностью исключить список, но верните только строку. как это
Другими словами, у вас есть foo = [some_string]
и вы делаете print foo
который, как сторона делает repr(some_string)
но заключает его в квадратные скобки, которые вы не хотите. Поэтому просто print repr(foo[0])
.
Кажется, что есть несколько вещей, необъяснимых:
Вы говорите, что полезный текст заключен в скобки по \xaaU
но в примере файла вместо 2 вхождений этого разделителя есть только \xaa
(отсутствует U
) рядом с началом, и ничего больше.
Ты говоришь
Я обнаружил, что re.findall(r '. +', Line1) разбивает на...
Это фактически отключает \n
(но не \r
!!) - я думал, что разрывы строк будут сохранены при попытке восстановить сообщение электронной почты.
>>> re.findall(r'.+', 'abc\r\ndef\r\n\r\n')
['abc\r', 'def\r', '\r']
То, что вы сделали вы с \r
символов? Вы протестировали многострочное сообщение? Вы протестировали файл с несколькими сообщениями?
Нужно угадать, кто или что предназначен для потребления вашей продукции; ты пишешь
Мне нужно разобрать текст по строкам и слово за словом
но вы, похоже, слишком озабочены печатью сообщения "разборчиво", например, \xab
вместо тарабарщины.
Похоже, что последние 6 или около того строк в вашем последнем коде (for msgline in msglines:
etc и т.д.) Должны быть отступом на один уровень.
Можно ли прояснить все вышесказанное?
В: Как прочитать файл? двоичный и текст вкраплены
A: Не утруждайте себя, просто прочитайте его как обычный текст, и вы сможете сохранить двоичную/текстовую дихотомию (иначе вы не сможете повторно использовать ее так же легко)
fh = open('/path/to/my/file.ext', 'r')
fh.read()
На всякий случай, если вы хотите по какой-то причине почитать двоичный код, вы просто добавляете ab ко второму входу open:
fh = open('/path/to/my/file.ext', 'rb')
Q: Устранить ненужные управляющие символы
A: Используйте модуль python re. Ваш следующий вопрос sorta спросит, как
Q: проанализировать сообщения между двумя \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, чтобы выяснить, какие файлы существуют/как проходить через них.
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.
open('yourfile.pst','rb')
которое может преодолеть глупость Windows.
re
library, например, чтобы делать то, что Perl делает с операторомm/.../
.