负前瞻 python 正则表达式

Posted

技术标签:

【中文标题】负前瞻 python 正则表达式【英文标题】:Negative look ahead python regex 【发布时间】:2012-04-14 16:21:10 【问题描述】:

当字符串 '02 d0' 没有出现在字符串中的特定位置时,我想匹配一个字节序列。这个两个字节的字符串不能出现的位置是字节位置 6 和 7,从右侧的第 0 个字节开始。

这是我一直用来测试的:

#!/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”时,我需要做什么来匹配?

【问题讨论】:

只有我一个人认为[0-9a-f][\da-f] 更具可读性吗? 你的意思是“位置 7 和 8”,对吧? 【参考方案1】:

前瞻是“零宽度”,这意味着它们不消耗任何字符。例如,这两个表达式永远不会匹配:

    (?=foo)bar (?!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

【讨论】:

为什么要使用 [\da-f]? @umayneverknow [\da-f] 匹配一个十六进制数字。等效地,可以使用[0-9a-f]

以上是关于负前瞻 python 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

负前瞻正则表达式

正则表达式前瞻(?=)后顾(?<)负前缀(?!)负后顾(?<!)

Java 正则表达式:负前瞻

正则表达式忽略分组顺序匹配(前瞻后顾负前瞻负后顾的应用)

Prometheus(公制)使用逆正则表达式匹配/负前瞻重新标记配置

正则表达式?: ?! ?=