My package manager is giving me a list of packages which are to be updated, I started the updated but wanted to see of which of these packages the major and minor version changed. I thought I could challenge myself to do this with some advanced Regex magic (involving referencing previous groups and using lookarounds) but I failed.
Let's say you have the following list of updatable packages, I want to match majorchange
and minorchange
, but not nochange
:
majorchange 1.2 -> 3.4
minorchange 1.2 -> 1.3
nochange 1.2 -> 1.2
My failed approach:
(\d+)[.-](\d+)[\w.+~-]* -> (?:(?!\1)\d+[.-]\d+[\w.+-]*|\d+[.-](?!\2)\d+[\w.+~-]*)
As you can see with tools like regex101, the problem is that I get too many matches thanks to backtracking which makes it possible to match the minor version as if it was the major version. Apparently I also cannot make the first group atomic using (?>…)
and match it again. It looks like a near miss.
astromancy 2.40.1+git20190410.b0871968d-2.1 -> 2.40.1+git20190410.b0871968d-2.2
byssine 3.02~a10-12.1 -> 3.02~a10-12.2
citigrade 84.87.20190511.bc4a9329cc-1.1 -> 84.87.20190511.bc4a9329cc-1.2
comiphorous 2+git20170807.10b2785-6.2 -> 2+git20170807.10b2785-6.3
didact 1+20100611git1f74ea7-1.1 -> 1+20100611git1f74ea7-1.2
disembogue 1550_20190429-2.1 -> 1550_20190429-2.2
dittography 0.0+git20171227.670229c-2.3 -> 0.0+git20171227.670229c-2.4
electrograph 1.22.4+20190423.9bc253e9-1.1 -> 1.22.4+20190423.9bc253e9-1.2
fenestral 19.04-1.1 -> 19.04-1.25.212~alpha2-7.2
gelastic 20190414-2.1 -> 20190414-2.2
hebetude 0.7.14+0-1.2 -> 0.7.14+0-1.3
ineluctable 1.1.1-1.1 -> 1.1.1-1.2
isothere 0.6.54-3.1 -> 0.6.54-3.2
jemadar 0.1+20130910-3.1 -> 0.1+20130910-3.2
kagu 1.0.0rc6+gitr3804_2b18fe1d885e-1.1 -> 1.0.0rc6+gitr3804_2b18fe1d885e-1.2
mackinaw 1.0.0.rc16-40.4 -> 1.0.0.rc16-40.5
merkin 1.1.9-1.1 -> 1.9.1-1.2
microsomatous 1.1.1b-1.1 -> 1.1.1b-1.2
mizzenmast 0.2.8-3.1 -> 0.2.8-3.2
monaxial 15.5-26.2 -> 15.5-26.3
nates 3.32.0-1.1 -> 3.32.0-2.1
ochroleucous v8.0-1.1 -> v8.0-1.2
ophic 0.176-2.1 -> 0.176-2.2
otiose 19.1.1+git.1557777841.63878672-1.1 -> 19.1.1+git.1557777841.63878672-1.2
quarterland 20190509-1.1 -> 20190509-1.2
quindecad 3.0.1~b08-1.1 -> 3.0.1~b08-1.2
quinsell 7.4.1+r270528-2.1 -> 7.4.1+r270528-2.2
rudstay 84.87+git20190418.d83e9d6-1.1 -> 84.87+git20190418.d83e9d6-1.2
snell 30.pre9-38.3 -> 30.pre10-17.4
thropple 1.0+git.e66999f-2.1 -> 1.0+git.e66999f-2.2
ullagone 0.7.0.1+gitr2726_872f0a83c98a-1.1 -> 0.7.0.1+gitr2726_872f0a83c98a-1.2
unguinous 0.2.1+20181004.20a0aae-1.2 -> 0.2.1+20181004.20a0aae-1.3
vaulty 2019_20190410-1.1 -> 2019_20190410-1.2
vitrail 18.09.6_ce-1.1 -> 18.09.6_ce-1.2
vivisepulture 1550_20190429-2.1 -> 1550_20190429-2.2
whitleather 3.0~rc1+git20170515.5a17f79-4.1 -> 3.0~rc1+git20170515.5a17f79-4.2
youthquake 3.12.2+20171213.567326a7-3.3 -> 3.12.2+20171213.567326a7-3.4
zamacueca 84.87.20190508.853b49d2-1.1 -> 84.87.20190508.853b49d2-1.2
zumbador p17-1024.15 -> p17-1024.16
(\d+)[.-](\d+)[\w.+~-]* -> (?:(?!\1)|(?:\1[.-](?!\2)))
This matches all major and minor version changes but does not match anything else. Of course this only works on packages that use a version format that starts with majorverson.minorversion
or majorversion-minorversion
. I don't see any packages with the second format but I took that from your regex.
Also, your test data does not contain any major version changes and only a single minor version change.
PS: after checking that, your regex would work if you include a single space at the beginning of the regex ;)