Негативное регулярное выражение python

Я хотел бы, чтобы регулярное выражение соответствовало последовательности байтов, когда строка «02 d0» не встречается в определенной позиции в строке. Позиция, в которой эта строка из двух байтов не может появиться, — это позиции 6 и 7 байтов, начиная с 0-го байта с правой стороны.

Это то, что я использовал для тестирования:

#!/usr/bin/python
import re

p0 = re.compile('^24 [\da-f]{2} 03 (01|03) [\da-f]{2} [\da-f]{2} [\da-f]{2} (([^0])|    (0[^2])|(02 [^d])|(02 d[^0])) 01 c2 [\da-f]{2} [\da-f]{2} [\da-f]{2} 23')
p1 = re.compile('^24 [\da-f]{2} 03 (01|03) [\da-f]{2} [\da-f]{2} [\da-f]{2} (([^0])|(0[^2])|(02 [^d])|(02 d[^0])) 01')
p2 = re.compile('^24 [\da-f]{2} 03 (01|03) [\da-f]{2} [\da-f]{2} [\da-f]{2} (([^0])|(0[^2])|(02 [^d])|(02 d[^0]))')
p3 = re.compile('^24 [\da-f]{2} 03 (01|03) [\da-f]{2} [\da-f]{2} [\da-f]{2} (?!02 d0) 01')
p4 = re.compile('^24 [\da-f]{2} 03 (01|03) [\da-f]{2} [\da-f]{2} [\da-f]{2} (?!02 d0)')

yes = '24 0f 03 01 42 ff 00 04 a2 01 c2 00 c5 e5 23'
no  = '24 0f 03 01 42 ff 00 02 d0 01 c2 00 c5 e5 23'

print p0.match(yes)  # fail
print p0.match(no)   # fail
print '\n'
print p1.match(yes)  # fail
print p1.match(no)   # fail
print '\n'
print p2.match(yes)  # PASS
print p2.match(no)   # fail
print '\n'
print p3.match(yes)  # fail
print p3.match(no)   # fail
print '\n'
print p4.match(yes)  # PASS
print p4.match(no)   # fail

Я просмотрел этот пример, но этот метод менее ограничительный, чем я необходимость. Может ли кто-нибудь объяснить, почему я могу правильно сопоставить только тогда, когда отрицательный взгляд вперед находится в конце строки? Что мне нужно сделать, чтобы соответствовать, когда «02 d0» не встречается в этой конкретной битовой позиции?


person Michael    schedule 31.03.2012    source источник
comment
Я единственный, кто думает, что [0-9a-f] более читаем, чем [\da-f]?   -  person ThiefMaster    schedule 31.03.2012
comment
Вы имеете в виду позиции 7 и 8, верно?   -  person Qtax    schedule 31.03.2012


Ответы (1)


Упреждения имеют «нулевую ширину», что означает, что они не потребляют никаких символов. Например, эти два выражения никогда не будут совпадать:

  1. (?=foo)bar
  2. (?!foo)foo

Чтобы убедиться, что число не является каким-то конкретным числом, вы можете использовать:

(?!42)\d\d # will match two digits that are not 42

В вашем случае это может выглядеть так:

(?!02)[\da-f]{2} (?!0d)[\da-f]{2}

or:

(?!02 d0)[\da-f]{2} [\da-f]{2}
person Qtax    schedule 31.03.2012
comment
Почему используется [\da-f]? - person umayneverknow; 10.02.2017
comment
@umayneverknow [\da-f] соответствует шестнадцатеричной цифре. Аналогично можно использовать [0-9a-f]. - person frederick99; 20.10.2017