Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I was wondering how I might align text using a regular expression. Here is an example input:
ABCDEFGHIJKLMNOPQRST|1234 ABCDEFGHI|12345 ABCDE|1234 ABCDEFGHIJKL|123 ABCDEFG|123456 ABCDEFGHIJKLMNO|12
I want to split at the pipeline and align everything to the right on the 45th char along. So something like this:
ABCDEFGHIJKLMNOPQRST 1234 ABCDEFGHI 12345 ABCDE 1234 ABCDEFGHIJKL 123 ABCDEFG 123456 ABCDEFGHIJKLMNO 12
So I would imagine using s/|/*t*/; where *t* some how aligns the text to the 45th char.

Any ideas? Thanks.

Replies are listed 'Best First'.
Re: Alignment of text using regex
by jettero (Monsignor) on Jan 16, 2007 at 17:58 UTC

    A regular may not be the best choice there. Personally, I'd split and choose split and printf. There are many other choices.

    my @a = split /\|/, $line; # we still split with a regular ... printf("%-43s %s\n", @a);

    -Paul

Re: Alignment of text using regex
by imp (Priest) on Jan 16, 2007 at 18:13 UTC
    While you can do this with a regex it wouldn't be as easy to maintain as an unrolled version using split and printf.

    Contrast this:

    use strict; use warnings; $/ = undef; my $data = <DATA>; $data =~ s{^(.*?)\|}{sprintf '%-45s', $1}meg; print $data; __DATA__ ABCDEFGHIJKLMNOPQRST|1234 ABCDEFGHI|12345 ABCDE|1234 ABCDEFGHIJKL|123 ABCDEFG|123456 ABCDEFGHIJKLMNO|12
    With:
    use strict; use warnings; while (my $line = <DATA>) { my ($lhs,$rhs) = split /\|/, $line, 2; printf "%-45s%s", $lhs,$rhs; } __DATA__ ABCDEFGHIJKLMNOPQRST|1234 ABCDEFGHI|12345 ABCDE|1234 ABCDEFGHIJKL|123 ABCDEFG|123456 ABCDEFGHIJKLMNO|12

      How about the best of both worlds?

      while(<DATA>) { s(\|){ ' ' x (45-pos) }e; print }
      A word spoken in Mind will reach its own level, in the objective world, by its own weight

        Your dark arts frigten me.

        -Paul

Re: Alignment of text using regex
by BrowserUk (Patriarch) on Jan 16, 2007 at 18:30 UTC
Re: Alignment of text using regex
by shigetsu (Hermit) on Jan 16, 2007 at 18:51 UTC

    While both, jettero & imp, have provided perfectly suitable solutions for aligning two or more values using a formatstring, you perhaps might be interested what format offers, especially if you become interested in having multiple values output in a formatted way, where, for example, the alignment differs from value to value.

    Example code

    #!/usr/bin/perl use strict; use warnings; my @elems = qw(left centered right); format = ------------------------------------------ @<<<<<<<<<<<<< @||||||||||| @>>>>>>>>>>>>> @elems ------------------------------------------ . write;

    outputs

    ------------------------------------------ left centered right ------------------------------------------

    Update: Added code.

Re: Alignment of text using regex
by madbombX (Hermit) on Jan 16, 2007 at 19:33 UTC
    Expanding on shigetsu's notion of using formatting (which I agree would be the best method here), you may want to look into Perl6::Form (Perl 6's version of format). It is more straightforward than what is being used in Perl 5 and will soon become the standard anyway.