Python正则表达式从二进制文件中提取数据块

时间:2014-04-01 18:16:29

标签: python regex

我是一个二进制文件。从该文件中我需要使用python正则表达式提取少量数据。

我需要提取存在于空字符集之间的非空字符集。

例如,这是主要字符集:

  

\ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ XFF \ XFE \ XFE \ X00 \ X00 \ X23 \ X41 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X41 \ X49 \ X57 \ X00 \ X00 \ X00 \ X00 \ X32 \ X41 \ X49 \ X57 \ X00 \ X00 \ X00 \ X00 \ X32 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X56 \ X65 \ X00 \ X35 \ X56

正则表达式应从上面的主集中提取以下字符集:

  

\ XFF \ XFE \ XFE \ X00 \ X00 \ X23 \ X41,   \ x41 \ x49 \ x57 \ x00 \ x00 \ x00 \ x00 \ x32 \ x41 \ x49 \ x57 \ x00 \ x00 \ x00 \ x00 \ x32和   \ X56 \ X65 \ X00 \ X35 \ X56

有一件事很重要,如果它连续获得超过5个空字节,那么只有它应该将这些空字符设置为分隔符。否则它应该将此空字节包含在非空字符中。正如您在给定示例中所看到的,提取的字符集中也存在少量空字符。

如果没有任何意义,请告诉我,我会尝试以更好的方式解释它。

先谢谢,

3 个答案:

答案 0 :(得分:1)

您可以将split和lstrip与list comprehension一起使用:

s='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\xfe\x00\x00\x23\x41\x00\x00\x00\x00\x00\x00\x00\x00\x41\x49\x57\x00\x00\x00\x00\x32\x41\x49\x57\x00\x00\x00\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x65\x00\x35\x56'
sp=s.split('\x00\x00\x00\x00\x00')
print [i.lstrip('\x00\\')  for i in sp if i != ""]

输出:

['\xff\xfe\xfe\x00\x00#A', 'AIW\x00\x00\x00\x002AIW\x00\x00\x00\x002', 'Ve\x005V']
  1. 根据5个零值分割整个数据。
  2. 列表中的
  3. ,查找是否有任何元素以nul开头,如果它开始删除它们(这适用于开始时可变数量的nul替换)。

答案 1 :(得分:1)

你可以在\x00{5,}分开 这是5或更多零。它是你指定的分隔线。

在Perl中,它是这样的

Perl测试用例

$strLangs =  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\xfe\x00\x00\x23\x41\x00\x00\x00\x00\x00\x00\x00\x00\x41\x49\x57\x00\x00\x00\x00\x32\x41\x49\x57\x00\x00\x00\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x65\x00\x35\x56";

# Remove leading zero's (5 or more)
$strLangs =~ s/^\x00{5,}//;

# Split on 5 or more 0's
@Alllangs = split /\x00{5,}/, $strLangs;

# Print each language characters
foreach $lang (@Alllangs)
{
    print "<";
    for ( split //, $lang ) {
       printf( "%x,", ord($_)); 
    }
    print ">\n";

}

输出&gt;&gt;

<ff,fe,fe,0,0,23,41,>
<41,49,57,0,0,0,0,32,41,49,57,0,0,0,0,32,>
<56,65,0,35,56,>

答案 2 :(得分:1)

以下是如何在Python中完成的。我不得不str.strip()关闭并且前导和尾随空格来获取正则表达式模式,以防止在re.split()返回的结果列表的开头包含额外的空字符串。

import re

data = ('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\xfe\x00\x00\x23\x41'
        '\x00\x00\x00\x00\x00\x00\x00\x00\x41\x49\x57\x00\x00\x00\x00\x32\x41'
        '\x49\x57\x00\x00\x00\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
        '\x00\x00\x00\x00\x00\x56\x65\x00\x35\x56'
        '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

chunks = re.split(r'\000{6,}', data.strip('\x00'))

# display results
print ',\n'.join(''.join('\\x'+ch.encode('hex_codec') for ch in chunk) 
                         for chunk in chunks),

输出:

\xff\xfe\xfe\x00\x00\x23\x41,
\x41\x49\x57\x00\x00\x00\x00\x32\x41\x49\x57\x00\x00\x00\x00\x32,
\x56\x65\x00\x35\x56