2016-09-01 5 views
3

Я использую RegEx для соответствия сообщений BGP в байтовой строке. Строка примера байт выглядит так:Regex on bytestring в Python 3

b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04'

\ XFF (8 раз) используются в качестве «фломастера», чтобы начать одно сообщение. Теперь я хочу разбить сообщения для анализа каждого из них.

messages = re.split(b'\xff{8}', payload) 

Соответствие прекрасно работает, но в моем массиве сообщений я получил несколько полей.

b'' 
b'' 
b'001304' 
b'' 
b'' 
b'001304' 

Может кто-нибудь объяснить это поведение? Почему между каждым (правильным расщепленным) сообщением есть два пустых поля. В больших байтовых строках иногда между каждыми сообщениями имеется только одно пустое поле.

+0

Возможно 'messages = re.split (b '(?: \ Xff) {8}', полезная нагрузка)'? –

ответ

1

Я думаю, что вы хотите, чтобы соответствовать 8 вхождений \xff, а не только 8 хвостовые f с (например \xfffffffff):

messages = re.split(b'(?:\xff){8}', payload) 
         ^^^ ^

Кроме того, есть только более чем один 8 последовательных \xff s в строке на конце , Вы можете использовать

messages = re.split(b'(?:(?:\xff){8})+', payload) 

Однако, что будет по-прежнему привести к тому, пустой первый элемент, если совпадение найдено в начале данных. Вы можете удалить часть в начале, до расщепления:

messages = re.split(b'(?:(?:\xff){8})+', re.sub(b'^(?:(?:\xff){8})+', b'', payload)) 

ОДНАКО, лучшая идея состоит в том, чтобы просто удалить пустые элементы со списком понимания или с Filter (kudos for testing goes to you):

messages = [x for x in re.split(b'(?:\xff){8}', payload) if x] 
# Or, the fastest way here as per the comments 
messages = list(filter(None, messages)) 

См. Обновленный Python 3 demo

+0

Исправить. Но ваше измененное регулярное выражение приводит к тому же пустым полям между правильными совпадениями. – iLLogical

+1

Я пытался показать, как это можно решить, шаг за шагом, увидеть последний пример кода и [демонстрацию в IDEONE] (https://ideone.com/HM0bXs). –

+0

Я думаю, что downvoter не понравился 're.sub'. Хотя это действительная идея, но мы действительно можем пропустить это и использовать понимание списка. Я обновил ответ. –