How do I compare strings non-ascii-betically?

S

Suzanne

I am new to Perl but I did a lot of web searching and haven't found an
answer to my problem.

I have to compare strings that are version numbers. I want to know if
a version number is less than or equal to another version number.

For example, version 3.2 is less than version 3.16. But when I
compare them, 3.16 is considered less. I tried the cmp function and
got the same results.

I could strip the contents after the '.' and compare them numerically
but it becomes difficult if the version number is 3.2.1.5 (for
example).

Any ideas? Thanks in advance.
 
B

Bill H

I am new to Perl but I did a lot of web searching and haven't found an
answer to my problem.

I have to compare strings that are version numbers.  I want to know if
a version number is less than or equal to another version number.

For example, version 3.2 is less than version 3.16.  But when I
compare them, 3.16 is considered less.  I tried the cmp function and
got the same results.

I could strip the contents after the '.' and compare them numerically
but it becomes difficult if the version number is 3.2.1.5 (for
example).

Any ideas?  Thanks in advance.

One way would be to split the versions on the ".", pad with zeros and
compare that way. Example (untested, typed in):

@versions = ("3.16","3.2");

for($i = 0;$i < @versions;$i++)
{
@thisone = split(/\./,$versions[$i]);
$temp = "";
foreach $a (@thisone)
{
$temp .= sprintf("%08i",$a);
}
$newversion[@newversion] = $temp."\t".$versions[$i];
}

@sorted = sort @newversion;

for($i = 0;$i < @sorted;$i++)
{
@this = split(/\t/,$sorted[$i]);
print "$this[1]\n";
}

Brute force, should work, could be improved with a hammer

Bill H
 
J

Jim Gibson

Suzanne said:
I am new to Perl but I did a lot of web searching and haven't found an
answer to my problem.

I have to compare strings that are version numbers. I want to know if
a version number is less than or equal to another version number.

For example, version 3.2 is less than version 3.16. But when I
compare them, 3.16 is considered less. I tried the cmp function and
got the same results.

I could strip the contents after the '.' and compare them numerically
but it becomes difficult if the version number is 3.2.1.5 (for
example).

Any ideas? Thanks in advance.

You need a multi-level comparison function that will split the two
input strings into parts separated by periods and compare each
corresponding part left to right, returning a comparison value for the
first difference it finds. Something like:

sub compare_version
{
my( $x, $y ) = @_;
my @x = split(/\./,$x);
my @y = split(/\./,$y);

while( @x && @y ) {
my $result = shift @x <=> shift @y;
return $result if $result;
}

if( @x ) {
return +1;
}elsif( @y ) {
return -1;
}else{
return 0;
}
}

This is why people try to use multi-level numbers such as 3.02 instead
of 3.2, so they will sort properly as is.
 
M

Mark Clements

Suzanne said:
I am new to Perl but I did a lot of web searching and haven't found an
answer to my problem.

I have to compare strings that are version numbers. I want to know if
a version number is less than or equal to another version number.

For example, version 3.2 is less than version 3.16. But when I
compare them, 3.16 is considered less. I tried the cmp function and
got the same results.

I could strip the contents after the '.' and compare them numerically
but it becomes difficult if the version number is 3.2.1.5 (for
example).

Any ideas? Thanks in advance.
Look at the version module, or maybe Perl::Version (I haven't looked at
the latter).

mark@hermes:~$ cat testversion.pl
use strict;
use warnings;

use version;

while(my $line=<DATA>){
chomp $line;

my ($raw1,$raw2) = split /\s+/,$line;

my ($v1,$v2) = map { qv($_) } ($raw1,$raw2);

my $v1greater = $v1 > $v2;
my $equal = $v1 == $v2;
my $v2greater = $v1 < $v2;

printf "v1=%9s v2=%9s v1greater=%d equal=%d v2greater=%d\n",
$v1,$v2,$v1greater,$equal,$v2greater;

}
__DATA__
1.1 1.2
1.1 1.1
1.2 1.1
1.10 1.2
1.1.1 1.1.1
1.1.2 1.1.1
1.1.2 1.1.10
3.2.1.5 3.2.1.4
3.2.1.5 3.2.10.5
3.2.2.5 3.2.1.5
mark@hermes:~$ perl testversion.pl
v1= v1.1 v2= v1.2 v1greater=0 equal=0 v2greater=1
v1= v1.1 v2= v1.1 v1greater=0 equal=1 v2greater=0
v1= v1.2 v2= v1.1 v1greater=1 equal=0 v2greater=0
v1= v1.10 v2= v1.2 v1greater=1 equal=0 v2greater=0
v1= 1.1.1 v2= 1.1.1 v1greater=0 equal=1 v2greater=0
v1= 1.1.2 v2= 1.1.1 v1greater=1 equal=0 v2greater=0
v1= 1.1.2 v2= 1.1.10 v1greater=0 equal=0 v2greater=1
v1= 3.2.1.5 v2= 3.2.1.4 v1greater=1 equal=0 v2greater=0
v1= 3.2.1.5 v2= 3.2.10.5 v1greater=0 equal=0 v2greater=1
v1= 3.2.2.5 v2= 3.2.1.5 v1greater=1 equal=0 v2greater=0
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top