我有一个大约5MB的二进制文件。。里面有很多穿插的文字。。和控制字符。。在
这实际上相当于SITATEX应用程序的outlook.pst文件(来自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。。很容易做到:
^{pr2}$如何在python中轻松地做到这一点。。在
在文本文件示例中。。。我有兴趣看。。BLLBBC。。。以及MVT和EA1123等等。在
请协助。。。如果在python中很难实现。。我将不得不仔细考虑perl本身的逻辑。。因为它(perl)不会给我带来很多错误,至少对于二进制和文本的循环部分来说。。还有正则表达式。在
谢谢。在
阅读您的答案/评论后更新1月2日
在看过S.Lott的评论和其他人之后。。。这就是我现在所在的地方。。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..
等(使用\xHH
格式)逐行打印。。但不要理会正常的可读文本。在
例如。。假设我有这个:假设^@
和{line1 = '^@UG^@^@^@^@^@^@^@^@^@^@BLLBBCC^X^X^X^X^X^X^X^X^X'
(在第一行)。在
当我在空闲时打印这行。。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和文本(其中它是可打印字符或空白)。在
还有。。有没有其他有用的注释可以很好地表达出来。在
谢谢。在
更新2011年1月2日-第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'
于1月5日添加信息:
@约翰·麦肯
1)\xaaU是消息之间的分隔符。。在示例中。。我可能刚刚漏掉了样品。请参阅下面的一条以\xaaU结尾的实际消息(但省略了)。
以下文本来自repr(msg between 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 DUE TO LATE ARVL ACFT\r\n CI / 0022 OFFLOAD OVERHANG PALLET DUE INADEQUATE PACKING LEADING TO \r\n SPACE PROBLEM
一旦可读文本结束。。。将忽略直到\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\xe8\x01\x00\x01JJJLOTG\x00\x01\xef\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\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 DUE TO LATE ARVL ACFT\r\n CI / 0022 OFFLOAD OVERHANG PALLET DUE INADEQUATE PACKING LEADING TO \r\n SPACE PROBLEM\x00D-\xedN\x00\x04\x1a\x00t<\x93\x01x\x00M_\x00"
2)知道“repr”后,我不再使用。+了。在
3)每条消息都是多行的。。我需要保留所有的控制字符来理解这个专有格式。。这就是为什么我需要雷普近距离观察。在
希望这能解释。。。这只是1000个邮件中的1个。。。有些是“SND”,有些是“RCV”。。。而对于'RCV'就不会有'000000'。。偶尔也有例外。。。但通常这是可以的。在
有什么进一步的建议吗。。我还在处理文件。。要完整地检索文本。。。有发送方和接收方地址。在
谢谢。在
Python也支持regex。我不会说Perl,所以我不知道您的Perl代码到底是做什么的,但是这个Python程序可能会帮助您:
这将得到文件中包含一个或多个ASCII可打印字符的所有字符串的列表。这可能不是你想要的,但是你可以从那里调整它。
请注意,如果您使用的是python3,那么您必须担心二进制数据和文本数据之间的区别,这会变得更加复杂。我假设你在python2中。
你说:
换句话说,你有
foo = [some_string]
,你正在做print foo
,作为一个边,repr(some_string)
但是你不想用方括号括起来。所以只要做print repr(foo[0])
。似乎有几件事无法解释:
您说有用的文本用
\xaaU
括起来,但是在示例文件中,在开头附近只有\xaa
(缺少U
),而没有其他内容。你说呢
实际上是剥离
\n
(但不是\r
!!)我认为在尝试恢复电子邮件时,换行是值得保留的。你对
\r
字符做了什么?你测试过多行信息吗?你测试过多消息文件吗?一个人可以猜测谁或什么人打算消耗你的输出;你写
但你似乎过于关心用
\xab
而不是乱七八糟地打印消息。最新代码中的最后6行左右(
for msgline in msglines:
等)应该缩进一级。有没有可能澄清以上所有的问题?
问:如何读取文件?二进制和文本穿插在一起
A:不用麻烦,只要把它当作普通文本来读,你就可以保持你的二进制/文本二分法(否则你就不能很容易地对它进行正则表达式)
如果以后出于某种原因想读取二进制文件,只需在open的第二个输入中添加一个b:
^{pr2}$Q:消除不必要的控制字符
A:使用pythonre模块。你的下一个问题是如何
Q:解析两个\xaa有用文本信息之间的消息\xaa(HEX'aa')
A:re模块有一个findall函数,它的工作方式与您(大多数)期望的一样。
Q:打印出所需资料
*A:有一个打印功能。。。
Q:把所有的线都圈起来。。以及更多文件。
我将让您找出os模块来确定存在哪些文件/如何遍历它们。
相关问题 更多 >
编程相关推荐