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

Dear Monks, I have a long list in the following style:
__DATA__ Some Company; Some Street 52 12345 City1 Another Company; Another Street 63 23456 City2 Yet Another Company; New Street 11 34546 City3
I need it in one line per company (i.e. the newline between the house number and the zip code should disappear). This code does not work:
use strict; use warnings; while(<DATA>) { $_=~s/([\w; ]+\d+)\n(\d{5})/$1$2/gms; print; }
I got something with the following workaround:
use strict; use warnings; while(<DATA>) { $_=~s/(\d{5})/;$1;/g; $_=~s/\n//gms; $_=~s/(\d{5}; \w+)/$1\n/g; print; }
but this seems ugly. Where is the catch? Many thanks! VE

Replies are listed 'Best First'.
Re: Regex with Newline
by JavaFan (Canon) on Aug 26, 2011 at 16:02 UTC
    while (<DATA>) { s/\n/ / if /;/; print; }

      so simple and elegant... I like it, a lot!!!

Re: Regex with Newline
by toolic (Bishop) on Aug 26, 2011 at 14:31 UTC
    Consider this approach:
    use warnings; use strict; my $prev; while(<DATA>) { if (/;/) { chomp; $prev = $_; } else { s/(\d{5})/$1;/; print "$prev; $_"; } } __DATA__ Some Company; Some Street 52 12345 City1 Another Company; Another Street 63 23456 City2 Yet Another Company; New Street 11 34546 City3
Re: Regex with Newline
by RichardK (Parson) on Aug 26, 2011 at 14:37 UTC

    As ';' is the only way to identify a company name, why not something like this?

    while (<DATA>) { chomp; print "\n" if /;/; print $_; } print "\n";
      I like the simplicity of this.
Re: Regex with Newline
by hardburn (Abbot) on Aug 26, 2011 at 14:24 UTC

    The while(<DATA>) only reads one line at a time. In the second example, the first regex replace will match the first line, while the second will match all lines (note that you'd be better off using chomp() for that purpose).

    In the first example, there is no single line that will match that regex, so the replacement never happens.


    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: Regex with Newline
by Anonymous Monk on Aug 26, 2011 at 14:43 UTC
    Thank you very much! Now it works with the following code:
    use strict; use warnings; while(<DATA>) { chomp; $_=~s/(\d{5} \w+)/ \1\n/g; print; } __DATA__ Some Company; Some Street 52 12345 City1 Another Company; Another Street 63 23456 City2 Yet Another Company; New Street 11 34546 City3
    Is this a reasonable code or I just have luck now?
    Many thanks!
    VE
      I think that is a bit "too clever".

      I was surprised but, this \1 idea did work although it generates a warning message.

      I would argue that easy to understand code is better. And it often executes faster!

      #!/usr/bin/perl -w use strict; my $previous_line; while (<DATA>) { if (/;/) { chomp; $previous_line = $_; } else { print "$previous_line; $_"; } } __DATA__ Some Company; Some Street 52 12345 City1 Another Company; Another Street 63 23456 City2 Yet Another Company; New Street 11 34546 City3