2012-03-31 18 views
7

Mi piacerebbe regex corrispondere una sequenza di byte quando la stringa '02 d0 'non si verifica in una posizione specifica nella stringa. La posizione in cui questa stringa di due byte non può verificarsi sono le posizioni dei byte 6 e 7 che iniziano con il byte 0 sul lato destro.Aspetto negativo python regex

Questo è quello che ho usato per il test:

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

Ho guardato this example, ma questo metodo è meno restrittive di cui ho bisogno. Qualcuno potrebbe spiegare perché posso solo abbinare correttamente quando lo sguardo negativo davanti è alla fine della stringa? Cosa devo fare per trovare una corrispondenza quando '02 d0 'non si verifica in questa posizione di bit specifica?

+1

io sono l'unico che pensa '[0-9a-f]' è più leggibile di '[\ da-f]'? – ThiefMaster

+0

Intendi "posizioni 7 e 8", giusto? – Qtax

risposta

11

Lookaheads sono "a larghezza zero", nel senso che non consumano alcun carattere. Ad esempio, queste due espressioni non sarà mai soddisfatta:

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

per assicurarsi che un numero è non un numero specifico, è possibile utilizzare:

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

In il tuo caso potrebbe sembrare:

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

o:

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

Questa è stata una spiegazione molto buona. Molte grazie! – Michael

+0

Perché viene utilizzato [\ da-f]? – umayneverknow

+0

@umayneverknow '[\ da-f]' corrisponde a una cifra esadecimale. Equivalentemente, '[0-9a-f]' può essere usato. – frederick99