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

时间:2022-01-12 06:13:54

I've a binary file. From that file I need to extract few chunk of data using python regular expression.

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

I need to extract non null characters-set present in-between null characters sets.

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

For example this is the main character set:

例如,这是主要的字符集:

\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 \ 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

The regex should extract below character sets from above master set:

regex应从上面的主集中提取以下字符集:

\xff\xfe\xfe\x00\x00\x23\x41, \x41\x49\x57\x00\x00\x00\x00\x32\x41\x49\x57\x00\x00\x00\x00\x32 and \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

One thing is important, If it gets more than 5 null bytes continuously then only it should treat these null characters set as separator..otherwise it should include this null bytes into no-null character. As you can see in given example few null characters are also present in extracted character set.

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

If its not making any sense please let me know I will try to explain it in a better manner.

如果没有任何意义,请让我知道我将尝试更好地解释它。

Thanks in Advance,

提前谢谢,

3 个解决方案

#1


1  

You could split on \x00{5,}
This is 5 or more zero's. Its the delimeter you specified.

您可以在\{5}上拆分,这是5个或更多的0。这是你指定的交货价表。

In Perl, its something like this

在Perl中,它是这样的

Perl test case

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";

}

Output >>

输出> >

<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  

You can use split and lstrip with list comprehension as:

你可以使用拆分和lstrip来理解列表:

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 != ""]

Output:

输出:

['\xff\xfe\xfe\x00\x00#A', 'AIW\x00\x00\x00\x002AIW\x00\x00\x00\x002', 'Ve\x005V']
  1. split entire data based on 5 nul values.
  2. 根据5个nul值分割整个数据。
  3. in the list, find if any element is starting with nul and if it's starting remove them (this works for variable number of nul replacement at start).
  4. 在列表中,查找是否有任何元素以nul开头,以及是否开始删除它们(这适用于开始时替换nul的变量数量)。

#3


1  

Here's how to do it in Python. I had to str.strip() off and leading and trailing nulls to get the regex pattern to prevent the inclusion of an extra empty string at the beginning of the list of results returned from re.split().

以下是如何在Python中实现它的方法。我必须先关闭,然后引导和拖尾,以获得regex模式,以防止在返回的结果列表开始时包含额外的空字符串。

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),

Output:

输出:

\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

#1


1  

You could split on \x00{5,}
This is 5 or more zero's. Its the delimeter you specified.

您可以在\{5}上拆分,这是5个或更多的0。这是你指定的交货价表。

In Perl, its something like this

在Perl中,它是这样的

Perl test case

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";

}

Output >>

输出> >

<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  

You can use split and lstrip with list comprehension as:

你可以使用拆分和lstrip来理解列表:

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 != ""]

Output:

输出:

['\xff\xfe\xfe\x00\x00#A', 'AIW\x00\x00\x00\x002AIW\x00\x00\x00\x002', 'Ve\x005V']
  1. split entire data based on 5 nul values.
  2. 根据5个nul值分割整个数据。
  3. in the list, find if any element is starting with nul and if it's starting remove them (this works for variable number of nul replacement at start).
  4. 在列表中,查找是否有任何元素以nul开头,以及是否开始删除它们(这适用于开始时替换nul的变量数量)。

#3


1  

Here's how to do it in Python. I had to str.strip() off and leading and trailing nulls to get the regex pattern to prevent the inclusion of an extra empty string at the beginning of the list of results returned from re.split().

以下是如何在Python中实现它的方法。我必须先关闭,然后引导和拖尾,以获得regex模式,以防止在返回的结果列表开始时包含额外的空字符串。

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),

Output:

输出:

\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