Несколько вещей:
Вы не упоминаете об этом, но используете ли вы модуль Perl Win32 :: TieRegistry ?Если нет, вы должны.Это значительно облегчит обработку реестра Windows.
В документации по Perl вы можете посмотреть Version String в Конструкторы скалярных значений ,Это значительно облегчит манипулирование строками версий.Строки версий имеют более одного десятичного знака или начинаются с буквы v
.Я всегда ставлю перед ними префикс v
, чтобы было понятно, что это такое.
Ниже приведен пример программы, показывающей, как их можно использовать в сравнениях:
#! /usr/bin/env perl
#
use strict;
use warnings;
my $version = v4.10.3;
for my $testVersion (v3.5.2, v4.4.1, v5.0.1) {
if ($version gt $testVersion) {
printf qq(Version %vd is greater than test %vd\n), $version, $testVersion;
}
else {
printf qq(Version %vd is less than test %vd\n), $version, $testVersion;
}
}
Обратите внимание, что я не могу просто напечатать строки версий.Я должен использовать printf
и sprintf
и использовать %vd
векторный десятичный формат , чтобы распечатать их.Печать строк версий с помощью регулярного оператора print
может привести к разного рода разрушениям, поскольку они действительно представляют собой Unicode-представления.Вы помещаете их в заявление для печати и не знаете, что получаете.
Также обратите внимание, что вы не заключаете в них кавычки!В противном случае вы просто сделаете их обычными строками.
НОВЫЙ ОТВЕТ
Я пытался найти способ преобразовать строку в v-строку без загрузки дополнительного пакета, например Perl :: Version или (Version), и я вдруг прочитал, что v-строки устарели, и я не хочу использовать устаревшую функцию.
Итак, давайте попробуем что-то еще...
Мы могли бы просто разделить номера версий на составляющие их компоненты в виде массивов:
v1.2.3 => $version[0] = 1, $version[1] = 2, $version[2] = 3
Используя следующий бит кода:
my @version = split /\./, "9.7.5";
my @minVersion = split /\./, "9.7"
Теперьмы можем каждую часть строки версии против другой.В приведенном выше примере я сравниваю 9
@version с 9
@version и т. Д. Если бы @version
было 9.6
, я бы сравнил 6
в @version
с 7
в @minVersion
и быстро обнаружил, что @minVersion
является более высоким номером версии.Однако в обеих вторых частях есть 7
.Я тогда смотрю на третий раздел.Упс!@minVersion
состоит только из двух разделов.Таким образом, @version
больше.
Вот подпрограмма, которая выполняет сравнение.Обратите внимание, что я также проверяю, что каждый раздел является целым числом с помощью регулярного выражения /^\d+$/
.Моя подпрограмма может возвращать четыре значения:
0
: оба имеют одинаковый размер 1
: первое число больше 2
: второеЧисло больше undef
: что-то не так.
Вот программа:
my $minVersion = "10.3.1.3";
my $userVersion = "10.3.2";
# Create the version arrays
my $result = compare($minVersion, $userVersion);
if (not defined $results) {
print "Non-version string detected!\n";
}
elsif ($result == 0) {
print "$minVersion and $userVersion are the same\n";
}
elsif ($result == 1) {
print "$minVersion is bigger than $userVersion\n";
}
elsif ($result == 2) {
print "$userVersion is bigger than $minVersion\n";
}
else {
print "Something is wrong\n";
}
sub compare {
my $version1 = shift;
my $version2 = shift;
my @versionList1 = split /\./, $version1;
my @versionList2 = split /\./, $version2;
my $result;
while (1) {
# Shift off the first value for comparison
# Returns undef if there are no more values to parse
my $versionCompare1 = shift @versionList1;
my $versionCompare2 = shift @versionList2;
# If both are empty, Versions Matched
if (not defined $versionCompare1 and not defined $versionCompare2) {
return 0;
}
# If $versionCompare1 is empty $version2 is bigger
if (not defined $versionCompare1) {
return 2;
}
# If $versionCompare2 is empty $version1 is bigger
if (not defined $versionCompare2) {
return 1;
}
# Make sure both are numeric or else there's an error
if ($versionCompare1 !~ /\^d+$/ or $versionCompare2 !~ /\^\d+$/) {
return;
}
if ($versionCompare1 > $versionCompare2) {
return 1;
}
if ($versionCompare2 > $versionCompare1) {
return 2;
}
}
}