2012-03-31 12 views
7

文字列の特定の位置に文字列'02 d0 'が出現しない場合、正規表現のバイトシーケンスを一致させたいと思います。この2バイトの文字列が現れない位置は、右側の0バイト目から始まるバイト位置6および7である。負の先読み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]思っ一つだけ' '[\ダ-F]'よりも読みやすいですか? – ThiefMaster

+0

あなたは「ポジション7とポジション8」を意味します、そうですか? – Qtax

答えて

11

ルックアヘッドは「ゼロ幅」です。つまり、文字を消費しません。例えば、これらの2つの式は一致しません:

  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

+0

[\ da-f]はなぜ使用されていますか? – umayneverknow

+0

@umayneverknow '[\ da-f]'は16進数と一致します。同様に、 '[0-9a-f]'を使うこともできます。 – frederick99