2012-03-31 6 views
7

Me gustaría regex coincidir con una secuencia de bytes cuando la cadena '02 d0 'no se produce en una posición específica en la cadena. La posición donde esta cadena de dos bytes no puede ocurrir son las posiciones de bytes 6 y 7 comenzando con el 0 ° byte en el lado derecho.Negative look ahead python regex

Esto es lo que he estado utilizando para la prueba:

#!/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 

Miré a this example, pero ese método es menos restrictiva de lo que necesito. ¿Alguien podría explicar por qué solo puedo unirme correctamente cuando la mirada negativa está al final del hilo? ¿Qué debo hacer para que coincida cuando '02 d0 'no ocurra en esta posición de bit específica?

+1

¿Soy el único que piensa que '[0-9a-f]' es más legible que '[\ da-f]'? – ThiefMaster

+0

¿Quiere decir "puestos 7 y 8", ¿verdad? – Qtax

Respuesta

11

Los cabezales Lookaheads tienen "ancho cero", lo que significa que no consumen ningún carácter. Por ejemplo, estas dos expresiones nunca coincidirán con:

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

Para asegurarse de que un número no es un número específico, que puede usar:

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

En su caso podría verse así:

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

o:

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

Esta fue una muy buena explicación. ¡Muchas gracias! – Michael

+0

¿Por qué se usa [\ da-f]? – umayneverknow

+0

@umayneverknow '[\ da-f]' coincide con un dígito hexadecimal. De manera equivalente, se puede usar '[0-9a-f]'. – frederick99