views:

194

answers:

1

Suppose two lines of text correspond to each other word by word except for the punctuation marks. How do I make vertical alignment of them?

For example:

$line1 = "I am English in fact";
$line2 = "Je suis anglais , en fait";

I want the output to be like this:

I   am     English       in   fact
Je  suis   anglais   ,   en   fait  .

I've come up with the following code, based on what I've learnt from the answers to my previous questions posted on SO and the "Formatted Output with printf" section of Learning Perl.

use strict;
use warnings;

my $line1 = "I am English in fact";
my $line2 = "Je suis anglais , en fait.";

my @array1 = split " ", $line1;
my @array2= split " ", $line2;

printf "%-9s" x @array1, @array1;
print "\n";
printf "%-9s" x @array2, @array2;
print "\n";

It is not satisfying. The output is this:

I        am       English  in       fact
Je       suis     anglais  ,        en       fait.

Can someone kindly give me some hints and suggestions to solve this problem?

Thanks :)

Updated

@ysth sent me on the right track! Thanks again:) Since I know what my own date looks like,for this sample, all I have to do is add the following line of code:

for ( my $i = 0; $i < @Array1 && $i < @Array2; ++$i ) {
    if ( $Array2[$i] =~ /,/ ) {
        splice( @Array1, $i, 0, '');
    }
}

Learning Perl briefly mentions that splice function can be used to remove or add items in the middle of array. Now thanks, I've enlarged my Perl knowledge stock again :)

+5  A: 

From your sample output, it seems what you are trying to do is to add extra empty string elements where there is just punctuation in one array but not in the other. This is fairly straightforward to do:

for ( my $i = 0; $i < @array1 && $i < @array2; ++$i ) {
    if ( $array1[$i] =~ /\w/ != $array2[$i] =~ /\w/ ) {
        if ( $array1[$i] =~ /\w/ ) {
            splice( @array1, $i, 0, '' );
        }
        else {
            splice( @array2, $i, 0, '' );
        }
    }
}

Or, somewhat more fancy, using flag bits en passant:

given ( $array1[$i] =~ /\w/ + 2 * $array2[$i] =~ /\w/ ) {
    when (1) { splice( @array1, $i, 0, '' ) }
    when (2) { splice( @array2, $i, 0, '' ) }
}
ysth
Your answer is not very straightforward to someone who is still reading "Learning Perl".
Ether
@ysth, thanks for sharing the code. But there seems to be a problem. After adding the code, Perl gives me this:Type of arg 1 to splice must be array (not null operation) at C:\test.pl line 13, near "'' )"Execution of C:\test.pl aborted due to compilation errors.
Mike
Mike
@ysth, thanks for the updated code. It works as expected. Loads of thanks :)
Mike
@ysth, the given when construct does not seem to work. I added use 5.010; and then ran the code, Perl gives me this: Use of uninitialized value $i in array element at C:\test.pl line 11.Use of uninitialized value $i in array element at C:\test.pl line 11.I am English in factJe suis anglais , en fait.
Mike
@yesth, sorry, it's my fault. After adding "for ( my $i = 0; $i < @array1 ++$i ) {" the given when construct works fine!
Mike
Thanks! I think I prefer the fancy version:)
Mike