作者:杭州琦琦妈_120 | 来源:互联网 | 2024-12-02 16:49
我正在尝试在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
及其状态相匹配,但没有看到按序列号命名的设备。我对这种语法缺少什么?
为什么不起作用
让我们看一行,看看您的正则表达式匹配什么:
# 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
<<<<# 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,然后捕获ONLINE
或AVAIL
到捕获组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