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

All, How to remove new lines, tabs and all spaces except one space between two words? An example is given below..
George Best
I want to remove all new line, tab and space chars but retain one space the two words like George Best.
Thanks and regards

2005-11-27 Retitled by planetscape, as per Monastery guidelines
Original title: 'How ro remove <code> \n <\code> between two words but retain one space'

Replies are listed 'Best First'.
Re: How to remove \n between two words but retain one space
by sk (Curate) on Nov 26, 2005 at 18:20 UTC
    my $str = "Hello\n\t\n World\n"; print $str; $str =~ s/\s+/ /g; print $str;

    Output

    Hello World Hello World

    Update: Please note this replaces all whitespace chars to a single space char. So if you have leading/trailing spaces please go with Your Mother's solution!

Re: How to remove \n between two words but retain one space
by Zaxo (Archbishop) on Nov 26, 2005 at 18:16 UTC

    One way to normalize whitespace:

    $foo = join ' ', split " ", $foo;
    That uses magical split.

    After Compline,
    Zaxo

Re: How to remove \n between two words but retain one space
by Your Mother (Archbishop) on Nov 26, 2005 at 18:28 UTC

    Something like this will do it.

    my $str = "George Best "; $str =~ s/(?<=[[:alpha:]])(?:\s\s+|[^\S ]+)(?=[[:alpha:]])/ /g; print "'$str'\n";

    (update: took off the pointless "s" from the s///) That might be more complicated (someone else might have a better one?) that than you need but I think it's good and will also fix things like--

    my $str = "George" . \n ."Best";

    It will not fix leading and trailing spaces. Just spacing between alpha characters.

      I believe that:

      s/(?<=[[:alpha:]])\s+(?=[[:alpha:]])/ /g;

      Will have the same effect as your posted expression. Although it will replace a single space character between two letters with a single space character (essentially a no-op), because it is a simpler pattern will actually take less time to execute. Below I am posting a simple benchmark I used to test this theory. If I have missed something please enlighten me.

      #!/usr/local/bin/perl -w use strict; use Benchmark; my(@tests) = <DATA>; timethese(400, {his => sub{ s/(?<=[[:alpha:]])(?:\s\s+|[^\S ]+)(?=[[:a +lpha:]])/ /g foreach(@tests); }, mine => sub{s/(?<=[[:alpha:]])\s+(?=[[:alpha:]])/ /g f +oreach(@tests); }}); __DATA__ A sting with weird A string without weird Another variety with more wierd Anotherthingwithnospaces something odd soemthing normal [me@mylinux]$ ./space.pl Benchmark: timing 400 iterations of his, mine... his: 0 wallclock secs ( 0.07 usr + 0.00 sys = 0.07 CPU) @ 57 +14.29/s (n=400) (warning: too few iterations for a reliable count) mine: 0 wallclock secs ( 0.03 usr + 0.00 sys = 0.03 CPU) @ 13 +333.33/s (n=400) (warning: too few iterations for a reliable count)

      They say that time changes things, but you actually have to change them yourself.

      —Andy Warhol

        You're right. I was trying to be overly correct I think in avoiding replacing " " with " "; it slows down the works considerably so it's not the way to go for this.

Re: How to remove \n between two words but retain one space
by GrandFather (Saint) on Nov 27, 2005 at 04:31 UTC

    To retain external white space while collapsing internal white space:

    use strict; use warnings; my $str = " Hello\n\t\n World \n"; print ">$str<\n"; $str =~ s/\b\s+\b/ /g; print ">$str<\n";

    Prints:

    > Hello World < > Hello World <

    DWIM is Perl's answer to Gödel