2014-04-01 4 views
2

У меня есть двоичный файл. Из этого файла мне нужно извлечь несколько фрагментов данных, используя регулярное выражение python.Python Regular Expression Extract Chunk of Data from Binary File

Мне нужно извлечь ненулевые символы, установленные между наборами нулевых символов.

Например это основной набор символов:

\ 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 нулевых байтов непрерывно, то только он должен рассматривать эти нулевые символы, выбранные в качестве separator..otherwise он должен включать этот нуль байты в символ no-null. Как вы можете видеть в данном примере, в выделенном наборе символов присутствуют несколько нулевых символов.

Если это не имеет никакого смысла, пожалуйста, сообщите мне, я постараюсь объяснить это наилучшим образом.

Спасибо заранее,

+2

Вы уверены, что вы будете хотеть использовать регулярные выражения для этого? – msvalkon

+0

Почему бы просто не разбить на '\ 000 {5,}'? – sln

+0

@msvalkon любой другой лучший/эффективный вариант? –

ответ

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

} 

Выход >>

<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,> 
+0

arr = re.split (r '\ 000 {5,}', data) отлично работает! Благодаря! –

+0

Рад, что он работает. Спасибо. – sln

+0

@Raza: В вашем вопросе вы сказали «*** больше *** 5 нулевых байтов непрерывно», поэтому вам, вероятно, понадобится 're.split (r '\ 000 {6,}', data)'. Кроме того, я получаю дополнительный элемент нулевой длины в начале с помощью модуля 're' Python, используя этот шаблон. – martineau

1

Вы можете использовать раскол и 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 != ""] 

Выход:

['\xff\xfe\xfe\x00\x00#A', 'AIW\x00\x00\x00\x002AIW\x00\x00\x00\x002', 'Ve\x005V'] 
  1. расщепленные целые данные, основанные на 5 NUL значений.
  2. в списке, найдите, если какой-либо элемент начинается с nul, и если он начинает их удалять (это работает для переменной количества нулевой замены при запуске).
+0

Спасибо за ваш быстрый ответ! Это прекрасно работает. –

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 
+0

Спасибо за ваш ответ! –