{ my $splitter= qr/\d+|[A-Za-z]+|[^0-9A-Za-z]+/; sub compare_version_string ($$) # returns <0, 0, >0 to indicate less, eq, or greater-than. # dies (exception) if no relation exists. { my ($left, $right)= @_; my @left= $left =~ /$splitter/g; my @right= $right =~ /$splitter/g; print "@left\n"; print "@right\n"; my $r; while (@left && @right) { $left= shift @left; $right= shift @right; if ($left =~ /^\d+$/ && $right =~ /^\d+$/) { # compare as numbers $r= $left <=> $right; return $r if $r; # or keep going if zero. } elsif ($left =~ /^[A-Za-z]+$/ && $right =~ /^[A-Za-z]+$/) { # compare as strings $r= $left cmp $right; return $r if $r; # or keep going if zero. } elsif ($left =~ /^[^0-9A-Za-z]+$/ && $right =~ /^[^0-9A-Za-z]+$/) { # delimter or "other", much match exact. die "version strings are not compatible.\n" unless $left eq $right; } else { # the parts are not of the same type die "version strings are not compatible.\n"; } } # one of the strings ran out of parts. return scalar(@left) <=> scalar(@right); } }