2012-03-31 63 views
7

我想正則表達式匹配字符串'02 d0'不發生在字符串中的特定位置時的字節序列。該字符串不能出現的位置是字節位置6和7,從右邊的第0字節開始。負面展望python正則表達式

這是我一直在用什麼來進行測試:

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

我看着this example,但該方法是限制較少比我更需要。有人能解釋爲什麼我只能在字符串末尾的負面預測時才能正確匹配嗎?當'02 d0'沒有出現在這個特定的位位置時,我需要做什麼來匹配?

+1

我是誰認爲'只有一個[0-9A-F]'比'[\ DA-F]'更具可讀性? – ThiefMaster 2012-03-31 01:18:26

+0

你的意思是「職位7和8」,對吧? – Qtax 2012-03-31 01:25:04

回答

11

Lookaheads是「零寬度」,這意味着它們不會消耗任何字符。例如,這兩個表達式不會匹配:

  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} 

或:

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

這是一個很好的解釋。非常感謝! – Michael 2012-04-02 19:18:31

+0

爲什麼使用[\ da-f]? – umayneverknow 2017-02-10 20:27:02

+0

@umayneverknow'[\ da-f]'匹配一個十六進制數字。等效地,可以使用'[0-9a-f]'。 – frederick99 2017-10-20 07:05:17