3

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 :)

ysth
  • 96,171
  • 6
  • 121
  • 214
Mike
  • 1,841
  • 5
  • 24
  • 34
  • If this is homework, you should add it as a tag. – Esteban Küber Nov 15 '09 at 07:08
  • 1
    @voyager, no offence, but what makes you think this is homework? does it look like homework? I'm not sure. But nope, this is definitely not homework. – Mike Nov 15 '09 at 07:34
  • 1
    Completely off-topic, but this approach *to translation* is a bad, bad idea. Languages rarely match each other so nicely word for word. – Telemachus Nov 15 '09 at 12:20
  • 2
    @Telemachus, well, I admit for translation this is not a nice idea. But I am also using a modified Lingua::Han::PinYin module, which can automatically retrieve Pinyin (pronunciations) to Chinese characters. I need to do some sort of vertical alignment. – Mike Nov 15 '09 at 12:40
  • @Mike: Cool, I took your example too literally. – Telemachus Nov 15 '09 at 12:40

1 Answers1

5

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
  • 96,171
  • 6
  • 121
  • 214
  • 2
    Your answer is not very straightforward to someone who is still reading "Learning Perl". – Ether Nov 15 '09 at 07:30
  • @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 Nov 15 '09 at 07:50
  • 1
    @Ether, although I am still reading the Llama book. Basically I can understand what @ysth wrote in his code. The ternary operator, the splice function, the && etc etc are all covered in the Book. But anyway thanks for the kindness :) – Mike Nov 15 '09 at 07:52
  • @ysth, thanks for the updated code. It works as expected. Loads of thanks :) – Mike Nov 15 '09 at 07:55
  • @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 fact Je suis anglais , en fait. – Mike Nov 15 '09 at 08:07
  • @yesth, sorry, it's my fault. After adding "for ( my $i = 0; $i < @array1 && $i < @array2; ++$i ) {" the given when construct works fine! – Mike Nov 15 '09 at 08:09
  • Thanks! I think I prefer the fancy version:) – Mike Nov 15 '09 at 08:10