user1051414
user1051414

Reputation: 49

perl how to do string alignment in perl

if I have two different strings like:

my $a = "garfieldaagt";
my $b = "field";

and I need to align them like

garfieldaagt
   field

to compare them, how could I do this?

Any ideas? Thanks

Upvotes: 0

Views: 2737

Answers (5)

Carlos Quijano
Carlos Quijano

Reputation: 1

Dynamic programming is the way to do it, you will get:

Garfield

Garied

to

Garfield

Gar-ie-d

This is an alignment. Any other thing can be prefix search, substrings search or what you have.

It is done comparing Garfield x Garied in the form of a matrix and find the longest and cheaper path from the first letter matching to the last, penalizing gaps.

If you wieght less common letters with higher score, the alignments may be better. But not necessary in the case of natural languages (english, spanish).

Regards

Upvotes: 0

nponeccop
nponeccop

Reputation: 13677

If you want to compare visually, see the other answer. If you want to compare programmatically, a few options are possible.

  1. You can use negative indices in strings and compare character-wise.
  2. You can use substr and compare smaller string with a substring of larger one
  3. You can use positive indices but add length difference to the index in the larger string

Finally, if you want to pad the strings to the same length with spaces, you can use sprintf in the same fashion as printf.

The second option is indeed what a programmer could write in production code:

my $x = "foobar";
my $y = "bar";

if ($y eq substr $x, -length($y))
{
    print "$y is a suffix of $x\n";
}

Regex or a full substring search is an overkill here.

Upvotes: 2

Zaid
Zaid

Reputation: 37146

This looks like an X-Y problem. I think this question is more about determining whether string B is contained inside string A.

While a substr/index combo is tempting to use, regular expressions are better-suited for this requirement:

my $stringA = 'garfieldaagt';
my $stringB = 'field';

print "'$stringB' contained in '$stringA'\n" if $stringA =~ /$stringB/;
# 'field' contained in 'garfieldaagt'

Using regexes will also address more complicated needs like case-insensitive matching.

See perldoc perlrequick for a quick introduction.

Upvotes: 0

user971401
user971401

Reputation:

You could use printf to print those strings with alignement :

printf "%8s\n%8s", $a, $b;

The number 8 here specifies how many characters are used for printing the strings, including whitespaces if needed.

Upvotes: 0

andrei
andrei

Reputation: 1008

You can use the index function to search for a string wihtin a string and then use the x repetition operator to align your substring to the position where it was found in the longer string.

$a = "garfield";
$b = "field";
print $a,"\n";
print " " x index($a,$b) ,$b,"\n";

Upvotes: 6

Related Questions