Strip equal portion of strings / version comparison

S

Stefan

Starting with:

$a = '1.1.2';
$b = '1.1.10';

Is there an elegant, one-liner way -- possibly using RE -- to yield:

$a = '2';
$b = '10';

In other words, strip out the beginning equal portion of 2 strings?

Moreover, how could you compare the original $a and $b such that $b >
$a (as in version comparisons)?

Thanks!
Stefan
 
G

Greg Bacon

: Starting with:
:
: $a = '1.1.2';
: $b = '1.1.10';
:
: Is there an elegant, one-liner way -- possibly using RE -- to yield:
:
: $a = '2';
: $b = '10';
:
: In other words, strip out the beginning equal portion of 2 strings?
:
: Moreover, how could you compare the original $a and $b such that $b >
: $a (as in version comparisons)?

Consider the following code:

$ cat try
#! /usr/bin/perl

use warnings;
use strict;

sub strip_equal {
my($a,$b) = @_;

return if $a eq $b;

local $_ = "$a;$b";
return ($2,$3) if /^(.+\.)(.+);\1(.+)$/;
}

sub cmpv {
my @a = split /\./, $a;
my @b = split /\./, $b;

while (@a && @b) {
my $a = shift @a;
my $b = shift @b;

$a <=> $b && return $a <=> $b;
}

@a <=> @b;
}

my @cases = (
["1.1.10", "1.1.2"],
["1.1.2", "1.1.2"],
["1.2.3", "4.5.6"],
);

$" = "][";
foreach my $case (@cases) {
our($a,$b) = @$case;

my @eq = strip_equal $a, $b;
my $cmpv = cmpv $a, $b;
print "a=$a, b=$b:\n",
" - strip_equal: [@eq]\n",
" - cmpv: $cmpv\n";
}
$ ./try
a=1.1.10, b=1.1.2:
- strip_equal: [10][2]
- cmpv: 1
a=1.1.2, b=1.1.2:
- strip_equal: []
- cmpv: 0
a=1.2.3, b=4.5.6:
- strip_equal: []
- cmpv: -1

Hope this helps,
Greg
 
S

Stefan

    sub strip_equal {
      my($a,$b) = @_;

      return if $a eq $b;

      local $_ = "$a;$b";
      return ($2,$3) if /^(.+\.)(.+);\1(.+)$/;
    }
    sub cmpv {
      my @a = split /\./, $a;
      my @b = split /\./, $b;

      while (@a && @b) {
        my $a = shift @a;
        my $b = shift @b;

        $a <=> $b && return $a <=> $b;
      }

      @a <=> @b;
    }
: snip :

Those are some great functions!! Thanks!!
 
G

Greg Bacon

: Those are some great functions!! Thanks!!

I'm glad you liked them. Happy new year!

Greg
 
C

comp.llang.perl.moderated

Starting with:

$a = '1.1.2';
$b = '1.1.10';

Is there an elegant, one-liner way -- possibly using RE -- to yield:

$a = '2';
$b = '10';

In other words, strip out the beginning equal portion of 2 strings?

Moreover, how could you compare the original $a and $b such that $b >
$a (as in version comparisons)?

Yet another way:

#! perl -l
use strict; use warnings;
use List::Util qw/max/;

my @s1 = split /\./, $a;
my $strip1 = $s1[-1];
my @s2 = split /\./, $b;
my $strip2 = $s2[-1];

CMP: {
for ( 0 .. max( $#s1, $#s2 ) ) {
my $res = ($s1[$_] || 0) <=> ($s2[$_] || 0);
$res == -1 and print "a is less than b"
and last CMP;
$res == 1 and print "a is greater than b"
and last CMP;
}
print "a is equal to b";
}
__END__
 

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,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top