正则表达式正向查找不符合预期

时间:2019-12-12 20:43:49

标签: python regex regex-lookarounds

我正在尝试在python正则表达式中使用正向后缀来匹配此示例zpool输出中的设备名称和序列号。我想我对后向语法不太了解,因为我无法匹配序列号。

我正在使用桌面上的Patterns应用程序对此进行沙箱处理。我还有其他一些关于后向断言的StackOverflow问题,但是我发现的东西似乎暗示着我处在正确的轨道上,到目前为止,我所看到的一切都没有清楚地表明我出了错。

pool                           ONLINE       0     0     0
  raidz2-0                       ONLINE       0     0     0
    diskid/DISK-PK2331PAG6ZLMT   ONLINE       0     0     0 
    da21                         ONLINE       0     0     0 
    diskid/DISK-PK2331PAG6ZVMT   ONLINE       0     0     0 
    diskid/DISK-PK2331PAG728ET   ONLINE       0     0     0 
    diskid/DISK-PK2331PAG6YGXT   ONLINE       0     0     0 

我想获取第一组中的设备或序列号,以及第二组中的状态(ONLINE | AVAIL)。我正在使用的正则表达式是:

^\s+(da\d+|(?<=diskid/DISK-)\S+)\s+(ONLINE|AVAIL)\s

它与设备名称da21及其状态相匹配,但没有看到按序列号命名的设备。我对这种语法缺少什么?

1 个答案:

答案 0 :(得分:1)

为什么不起作用

让我们看一行,看看您的正则表达式匹配什么:

# your regex
^\s+(da\d+|(?<=diskid/DISK-)\S+)\s+(ONLINE|AVAIL)\s

# your string
    diskid/DISK-PK2331PAG6ZLMT   ONLINE       0     0     0
<                     # ^ assert position at start of string
^^^^                  # \s+ match one or more whitespace characters
    ^!                # da\d+ matches d, fails to match a, backtrack; try next alternation
<<<<<!                # (?<=diskid/DISK-) assert what precedes matches the lookbehind
# This fails because the text to the left of the position that the parser is at does
#     not match diskid/DISK- (it's four spaces as was previously matched by \s+)

如何解决?

有多种正则表达式模式可以满足您要完成的任务:

选项1:单个捕获组

如果\S+之前是diskid/DISK-da\d+,则捕获到捕获组1,然后捕获ONLINEAVAIL到捕获组2。 / p>

((?<=diskid/DISK-)\S+|da\d+)\s+(ONLINE|AVAIL)\b

Pro:一个捕获组
缺点:无法确保第一个捕获组位于行的开头

选项2:锚定到行的开头

如果\S+之前是diskid/DISK-,则将da\d+捕获到捕获组1中,或者将ONLINE捕获到捕获组2中,然后将AVAIL^\s+(?:diskid/DISK-(\S+)|(da\d+))\s+(ONLINE|AVAIL)\b 捕获到捕获中第3组。

^\s+

Pro:停在行首-我们可以确保这是我们要匹配的数据(regex) 缺点:两个捕获组(我们不能将两个不同的数据集和两个不同的条件集(用于将字符串添加到一个捕获组中)

选项3:使用PyPi regex

我们可以很容易地使用^\s+(?|diskid/DISK-(\S+)|(da\d+))\s+(ONLINE|AVAIL)\b ^ # same as option 2, but uses branch reset 库来完成此操作,从而使我们成为一组并声明其在字符串中的位置。

分支重置方法(交替产生一个捕获组,而不是两个):

name