2012-03-31 12 views
7

Tôi muốn regex khớp với chuỗi byte khi chuỗi '02 d0 'không xuất hiện ở vị trí cụ thể trong chuỗi. Vị trí mà chuỗi này của hai byte không thể xảy ra là các vị trí byte 6 và 7 bắt đầu bằng byte thứ 0 ở phía bên tay phải.Nhìn tiêu cực trước python regex

Đây là những gì tôi đã được sử dụng để thử nghiệm:

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

Tôi nhìn this example, nhưng phương pháp đó là ít hạn chế hơn tôi cần. Ai đó có thể giải thích lý do tại sao tôi chỉ có thể phù hợp đúng khi nhìn tiêu cực phía trước là ở cuối chuỗi? Tôi cần phải làm gì để phù hợp khi '02 d0 'không xảy ra ở vị trí bit cụ thể này?

+1

Tôi là người duy nhất nghĩ '[0-9a-f]' là dễ đọc hơn so '[\ da-f]'? – ThiefMaster

+0

Bạn có nghĩa là "vị trí 7 và 8", phải không? – Qtax

Trả lời

11

Mặt nhìn là "không có chiều rộng", nghĩa là chúng không tiêu thụ bất kỳ ký tự nào. Ví dụ, hai biểu thức này sẽ không bao giờ phù hợp:

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

Để đảm bảo một số không được một số số lượng cụ thể, bạn có thể sử dụng:

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

Trong trường hợp của bạn có thể trông giống như:

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

hay:

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

Đây là một lời giải thích rất tốt. Cảm ơn rất nhiều! – Michael

+0

Tại sao [\ da-f] được sử dụng? – umayneverknow

+0

@umayneverknow '[\ da-f]' khớp với một chữ số hex. Tương đương, '[0-9a-f]' có thể được sử dụng. – frederick99