2009-05-14 2 views
1

Я борюсь с проверкой действительности номеров версий в Perl. Правильный номер версии, как это:Проверка правильности номера версии с Perl

  • Запускает либо с V или верами,
  • После этого число, если 0, то никаких других цифр не допускается в этой части (например, 10, 3993 и 0 ok, 01 нет),
  • После этого полная остановка, номер, полная остановка, номер, полная остановка и номер.

I.e. действительный номер версии может выглядеть примерно как v0.123.45.678 или ver18.493.039.1.

я придумал следующее регулярное выражение:

if ($ver_string !~ m/^v(er)?(0{1}\.)|([1-9]+\d*\.)\d+\.\d+\.\d+/) 
{ 
    #print error 
} 

Но это не работает, потому что номер версии, как verer01.34.56.78 получает принято. Я не могу понять этого, я знаю, что Perl имеет тенденцию быть жадным, но не должен ли он (v)? убедитесь, что может быть максимум один «er»? И почему не 0 {1}. соответствует только «0.», вместо того, чтобы принимать «01». также?

Это регулярное выражение действительно зацепило вещь «rere»: m/^ v (er)? [0-9.] + /, Но я не вижу, где я разрешаю это в своей попытке.

ответ

7

Ваша проблема в том, что или - | - вы используете, разбивая весь узор на две части. A | будет охватывать скобки или конец выражения, а не только на двух соседних элементах.

Вам нужно добавить некоторые дополнительные скобки, чтобы показать, какую часть выражения вы хотите или-ed. Таким образом, первый шаг к фиксации ваш шаблон будет:

^v(er)?((0{1}\.)|([1-9]+\d*\.))\d+\.\d+\.\d+ 

Вы также хотите положить $ в конце, чтобы гарантировать, что нет ни одного ложных символов в конце номера версии.

Кроме того, помещение {1} не является обязательным, это означает, что предыдущий элемент был установлен точно по умолчанию. Однако вы можете использовать {3} в конце вашего шаблона, так как вы хотите, чтобы в конце были трехточечные группы.

Аналогичным образом вам не нужен + после [1-9], так как другие цифры будут захвачены \d*.

И мы также можем удалить незащищенные кронштейны.

Таким образом, вы можете упростить Паттен к следующему:

^v(er)?(0|[1-9]\d*)(.\d+){3}$ 
+0

Это работает, отлично! Спасибо! – Makis

1

Вы можете сделать это с помощью одного регулярного выражения, или вы могли бы сделать это в 2 этапа, второй шаг в том, чтобы проверить, что первый номер Безразлично 't начинаться с 0.

BTW, я обычно использую [0-9] вместо \ d для чисел, есть много символов, которые классифицируются как числа в стандарте Unicode (и, следовательно, на Perl), что вы можете не хотеть иметь дело.

Вот пример кода, подкатегория version_ok, где все происходит.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Test::More tests => 7; 

while(<DATA>) 
    { chomp; 
    my($version, $expected)= split /\s*=>\s*/; 
    is(version_ok($version), $expected, $version); 
    } 

sub version_ok 
    { my($version)[email protected]_; 
    if($version=~ m{^v(?:er)?  # starts with v or ver 
         ([0-9]+)  # the first number 
         (?:\.[0-9]+){3} # 3 times dot number 
        $}x)    # end 
     { if($1 =~ m{^0[0-9]})   
      { return 0; }    # no good: first number starts with 0 
     else 
      { return 1; } 
     } 
    else 
     { return 0; } 
    } 


__DATA__ 
v0.123.45.678  => 1 
ver18.493.039.1 => 1 
verer01.34.56.78 => 0 
v01.5.5.5   => 0 
ver101.5.5.5  => 1 
ver101.5.5.  => 0 
ver101.5.5   => 0 
0

Регулярное выражение может работать для ваших тестов, но модуль CPAN Perl::Version, казалось бы, как самый лучший вариант, с двумя оговорками:

  • не пробовал сам
  • кажется, что последний выпуск модуля был в 2007 году - вид делает его рекурсивной проблемой
+0

Хотя мне всегда нравится рекомендовать CPAN, Perl :: Version здесь не подходит. Он предназначен для анализа номеров версий, используемых модулями CPAN, и Makis пытается проверить другой формат. (Он просто кодирует чек на Perl.) – cjm

Смежные вопросы