以下正则表达式适用于PCRE,Java和.NET,但不适用于Python或Golang。任何线索如何涵盖最后两个将非常感激。最好有一个正则表达式适合所有人,但我怀疑需要两个或更多。
https://regex101.com/r/E0iVVS/1
^(?<VersionTripple>(?<Major>0|[1-9][0-9]*)\.(?<Minor>0|[1-9][0-9]*)\.(?<Patch>0|[1-9][0-9]*)){1}(?<Tags>(?:\-(?<Prerelease>(?:(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})|(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)|(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)){1}(?:\.(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})|\.(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)|\.(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+))*){1}){0,1}(?:\+(?<Meta>(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))){0,1})$
扩展了一些评论:
^
(?<VersionTripple>
(?# Version fields are either zero or numeric with no leading zeros.)
(?<Major>0|[1-9][0-9]*)
\.
(?<Minor>0|[1-9][0-9]*)
\.
(?<Patch>0|[1-9][0-9]*)
){1}
(?<Tags>
(?# Either a prerelease tag or a prerelease tag followed by a build meta tag.)
(?:
(?# Prelease tags are preceded by a single dash and have one or more dot seperated identifiers.)
\-
(?<Prerelease>
(?:
(?# Look ahead, is it just zero? Then claim a zero.)
(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})
|
(?# Look ahead, is it pure numeric? Then claim the digits.)
(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)
|
(?# Look ahead, is it alphanumeric? Take them all.)
(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)
){1}
(?:
(?# Look ahead, is it just zero? Then claim a zero.)
\.(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})
|
(?# Look ahead, is it pure numeric? Then claim the digits.)
\.(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)
|
(?# Look ahead, is it alphanumeric? Take them all.)
\.(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)
)*
){1}
){0,1}
(?:
(?# Build meta tag is preceded by a plus symbol and followed by one or more dot seperated fields)
\+
(?<Meta>(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))
){0,1}
)
$
测试数据:
0.0.4
1.2.3
10.20.30
1.1.2-prerelease+meta
1.1.2+meta
1.1.2+meta-valid
1.0.0-alpha
1.0.0-beta
1.0.0-alpha.beta
1.0.0-alpha.beta.1
1.0.0-alpha.1
1.0.0-alpha0.valid
1.0.0-alpha.0valid
1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
1.0.0-rc.1+build.1
2.0.0-rc.1+build.123
1.2.3-beta
10.2.3-DEV-SNAPSHOT
1.2.3-SNAPSHOT-123
1.0.0
2.0.0
1.1.7
2.0.0+build.1848
2.0.1-alpha.1227
1.0.0-alpha+beta
1.2.3----RC-SNAPSHOT.12.9.1--.12+788
1.2.3----R-S.12.9.1--.12+meta
1.2.3----RC-SNAPSHOT.12.9.1--.12
1.0.0+0.build.1-rc.10000aaa-kk-0.1
99999999999999999999999.999999999999999999.99999999999999999
Begin Invalid
1
1.2
1.2.3-0123
1.2.3-0123.0123
1.1.2+.123
+invalid
-invalid
-invalid+invalid
-invalid.01
alpha
alpha.beta
alpha.beta.1
alpha.1
alpha+beta
alpha_beta
alpha.
alpha..
beta\
1.0.0-alpha_beta
-alpha.
1.0.0-alpha..
1.0.0-alpha..1
1.0.0-alpha...1
1.0.0-alpha....1
1.0.0-alpha.....1
1.0.0-alpha......1
1.0.0-alpha.......1
01.1.1
1.01.1
1.1.01
1.2
1.2.3.DEV
1.2-SNAPSHOT
1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788
1.2-RC-SNAPSHOT
-1.0.3-gamma+b7718
+justmeta
9.8.7+meta+meta
9.8.7-whatever+meta+meta
99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12
答案 0 :(得分:1)
根据@WiktorStribiżew的建议,我修改了命名捕获组并删除了冗余量词。它现在正在regex101.com(v3)处理除了golang之外的所有事情。看起来我们只需要建议golang用户抓住go-pcre library。
如果我发现任何更有效/更正确的方法,我会更新这篇文章。
^(?<VersionTripple>(?<Major>0|[1-9][0-9]*)\.(?<Minor>0|[1-9][0-9]*)\.(?<Patch>0|[1-9][0-9]*))(?<Tags>(?:\-(?<Prerelease>(?:(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})|(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)|(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)){1}(?:\.(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})|\.(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)|\.(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+))*)){0,1}(?:\+(?<Meta>(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))){0,1})$
带评论的扩展版本:
^
(?<VersionTripple>
(?# Version fields are either zero or numeric with no leading zeros.)
(?<Major>0|[1-9][0-9]*)
\.
(?<Minor>0|[1-9][0-9]*)
\.
(?<Patch>0|[1-9][0-9]*)
)
(?<Tags>
(?# Either a prerelease tag or a prerelease tag followed by a build meta tag.)
(?:
(?# Prelease tags are preceded by a single dash and have one or more dot seperated identifiers.)
\-
(?<Prerelease>
(?:
(?# Look ahead, is it just zero? Then claim a zero.)
(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})
|
(?# Look ahead, is it pure numeric? Then claim the digits.)
(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)
|
(?# Look ahead, is it alphanumeric? Take them all.)
(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)
){1}
(?:
(?# Look ahead, is it just zero? Then claim a zero.)
\.(?=[0]{1}[0-9A-Za-z-]{0})(?:[0]{1})
|
(?# Look ahead, is it pure numeric? Then claim the digits.)
\.(?=[1-9]{1}[0-9]*[A-Za-z]{0})(?:[0-9]+)
|
(?# Look ahead, is it alphanumeric? Take them all.)
\.(?=[0-9]*[A-Za-z-]+[0-9A-Za-z-]*)(?:[0-9A-Za-z-]+)
)*
)
){0,1}
(?:
(?# Build meta tag is preceded by a plus symbol and followed by one or more dot seperated fields)
\+
(?<Meta>(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))
){0,1}
)
$