Как найти размер шестнадцатеричной строки в байтах, используя Python3 (с регулярным выражением) - PullRequest
0 голосов
/ 27 февраля 2019

Мне поручено написать программу на Python 3. Я новичок в Python.

Мне нужно получить данные Hex из .bin-файла, а затем разбивать данные каждый раз, когда я вижу возникновениеконкретный шестнадцатеричный шаблон (например: каждый кусок начинается с 01 03).Наконец, мне нужно вывести количество разделов и размер (в байтах) каждого чанка.

Пока что я прочитал данные из файла .bin и использовал re.findall для разделения каждого куска данных.Мое выражение регулярного выражения выглядит примерно так:

b "\ x01 \ x03 (? (?! \ X01 \ x03).) *"

re.findall работает хорошо, но теперь у меня естьсписок из примерно 300 шестнадцатеричных блоков (так как я использовал re.findall), и теперь я не знаю, как проверить размер в байтах для каждого блока.Может кто-то помочь мне с этим?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Вы можете использовать enumerate:

regex = b'\x01\x03(?(?!\x01\x03).)*'

chunk_lengths = {index: len(chunk) for index, chunk in enumerate(re.findall(regex, data))}

Вы изначально использовали re.findall для получения каждого фрагмента в исходных данных, который следует вашему заданному регулярному выражению.Это bytes объекты, которые имеют четко определенную длину (количество байтов в них).

С помощью оператора len мы можем найти длину каждого чанка, и они сформируютзначения нашего словаря.Если бы мы сделали [len(chunk) for chunk in re.findall(regex, data))], это дало бы нам список длин всех найденных фрагментов, в порядке их поиска (это будет важно позже).

enumerateявляется встроенной функцией, которая позволяет «пометить» индекс (по умолчанию начиная с 0) для некоторого итерируемого объекта.Итак, скажем, у вас есть list [5, 3, 4], представляющий куски длины.Если вы примените enumerate к нему, вы получите tuple s (0, 5) (индекс 0, длина 5), (1, 3) (индекс 1, длина 3) и (2, 4) (индекс 2, длина 4).

Теперь, собрав все вместе в dict понимании, мы становимся более способными получить доступ к длинам фрагментов по индексу, созданному enumerate.Поскольку, как отмечено выше, findall возвращает список результатов по порядку, а перечисление также работает по порядку, индекс, созданный с помощью enumerate, также является относительной позицией фрагмента в исходных данных.

0 голосов
/ 27 февраля 2019

Я предлагаю

l = re.compile("\x01\x03(?(?!\x01\x03).)*").split(s)
len(l) - 1 

Результат теста:

>>> re.compile(r"\x01\x03").split(b"\x01\x03\0x4\0x5\x01\x03\0x6\0x7")
['', '\x00x4\x00x5', '\x00x6\x00x7']

Конечно, вы должны убедиться, что регулярное выражение верно.

...