我正在尝试编写一个 Python 库来解析我们的版本格式字符串。(简化的)版本字符串格式如下:
<product>-<x>.<y>.<z>[-alpha|beta|rc[.<n>]][.<extra>]][.centos|redhat|win][.snb|ivb]
这是:
- 产品,即
foo
- 数字版本,即:
0.1.0
- [可选] 预发布信息,即:
beta
,rc.1
,alpha.extrainfo
- 【可选】操作系统,即:
centos
- [可选] 平台,即:
snb
,ivb
所以以下是有效的版本字符串:
1) foo-1.2.3
2) foo-2.3.4-alpha
3) foo-3.4.5-rc.2
4) foo-4.5.6-rc.2.extra
5) withos-5.6.7.centos
6) osandextra-7.8.9-rc.extra.redhat
7) all-4.4.4-rc.1.extra.centos.ivb
对于所有这些示例,以下正则表达式都可以正常工作:
^(?P<prod>\w+)-(?P<maj>\d).(?P<min>\d).(?P<bug>\d)(?:-(?P<pre>alpha|beta|rc)(?:\.(?P<pre_n>\d))?(?:\.(?P<pre_x>\w+))?)?(?:\.(?P<os>centos|redhat|win))?(?:\.(?P<plat>snb|ivb))?$
但是问题出现在这种类型的版本中(没有“额外”的预发布信息,但有操作系统和/或平台):
8) issue-0.1.0-beta.redhat.snb
使用上面的正则表达式,对于字符串 #8,在预发布的额外信息中而不是组redhat
中被拾取。pre_x
os
我尝试使用后视来避免选择 os 或平台字符串pre_x
:
...(?:\.(?P<pre_x>\w+))?(?<!centos|redhat|win|ivb|snb))...
那是:
^(?P<prod>\w+)-(?P<maj>\d).(?P<min>\d).(?P<bug>\d)(?:-(?P<pre>alpha|beta|rc)(?:\.(?P<pre_n>\d))?(?:\.(?P<pre_x>\w+))?(?<!centos|redhat|win|ivb|snb))?(?:\.(?P<os>centos|redhat|win))?(?:\.(?P<plat>snb|ivb))?$
如果 Python 的标准模块re
可以接受可变宽度后视,这将正常工作。我宁愿尝试坚持标准模块,而不是使用正则表达式,因为我的库很可能被分发到大量机器上,我想在这些机器上限制依赖关系。
关于如何实现这一目标的任何想法?
我的 regex101 链接:https ://regex101.com/r/bH0qI7/3
[对于那些感兴趣的人,这是我实际使用的完整正则表达式:https://regex101.com/r/lX7nI6/2]