Ronnie Doorzon has asked for the wisdom of the Perl Monks concerning the following question:

I have a line that contains spaces which I want to replace
except for the last space.
eg: replace
$line = '<br> 2<br> 3<br> 4';
into
$line = '<br>&nbsp 2<br>&nbsp&nbsp 3<br>&nbsp&nbsp&nbsp 4';
The number of spaces can range from 0 to 50
Currently I'm doing this with many s/// lines but there should be a better way.
sub convert_line_1 { my $line_convert = shift; $line_convert =~ s/(\s{5})/\&nbsp\&nbsp\&nbsp\&nbsp /g; $line_convert =~ s/(\s{4})/\&nbsp\&nbsp\&nbsp /g; $line_convert =~ s/(\s{3})/\&nbsp\&nbsp /g; $line_convert =~ s/(\s{2})/\&nbsp /g; return($line_convert); } sub convert_line_2 { my $line_convert = shift; $line_convert =~ s/&nbsp&nbsp&nbsp&nbsp / /g; $line_convert =~ s/&nbsp&nbsp&nbsp / /g; $line_convert =~ s/&nbsp&nbsp / /g; $line_convert =~ s/&nbsp / /g; return($line_convert); }

Replies are listed 'Best First'.
Re: Replace a word in a line except for the last char of the word?
by Roy Johnson (Monsignor) on Mar 11, 2005 at 12:03 UTC
    s/ (?= )/&nbsp;/g;

    Caution: Contents may have been coded under pressure.
      Allow me to explain :-)

      (?=) matches only if what's between the "=" and the ")" is found to the right of the expression. This means the expression matches a space *only* if it is followed by another space.

Re: Replace a word in a line except for the last char of the word?
by cog (Parson) on Mar 11, 2005 at 12:26 UTC
    A few notes on your code:
    • In HTML, it's &nbsp;, and not &nbsp; you are missing the semicolons
    • Your substitutions have unnecessary brackets. (\s{5}) will match the same as \s{5}. The difference is that the brackets will capture those spaces into $1, but you don't seem to need that here
    • On the right hand side of substitutions, you don't need to escape the ampersand character
    • On your subroutines (or code blocks, for that matter), try to indent things (not sure if you just missed that because of pasting the code here)

    Hope you live a happier life because of this :-)

Re: Replace a word in a line except for the last char of the word?
by gube (Parson) on Mar 11, 2005 at 12:19 UTC

    Hi try this,

    $line = '<br> 2<br> 3<br> 4'; $line =~ s#(?= )#&nbsp#gsi; while ($line =~ s#(&nbsp) (&nbsp)#$1$2#gsi) { } print $line; o/p: <br>&nbsp&nbsp 2<br>&nbsp&nbsp&nbsp 3<br>&nbsp&nbsp&nbsp 4

    gube
Re: Replace a word in a line except for the last char of the word?
by dmorelli (Scribe) on Mar 11, 2005 at 14:11 UTC
    Hm. Some of these are so long. This seems to do the job.

    s/ +( )/&nbsp;$1/g

    As mentioned by cog, be mindful that it must be &nbsp; with the semicolon.

Re: Replace a word in a line except for the last char of the word?
by perlsen (Chaplain) on Mar 11, 2005 at 12:58 UTC

    Hi, just try the below code (is this meet your requirement?)

    my $line = '<br> 2<br> 3<br> 4'; my $temp = $line; while ($temp =~m#(<br>)(.+?)( \d+)#gsi) { my $full= $&; my $text=$1; my $space = "$2"; my $digit = "$3"; my @arr=(); (@arr) = $space =~s#( )# #gsi; my $nbsptext = "&nbsp;" x "@arr"; $line =~s#$full#${text}${nbsptext}${digit}#gsi; $full=""; } print $line; output: <br>&nbsp; 2<br>&nbsp;&nbsp; 3<br>&nbsp;&nbsp; 4
Re: Replace a word in a line except for the last char of the word?
by Ronnie Doorzon (Initiate) on Mar 11, 2005 at 14:38 UTC
    Thanks Monks for the great and quick replies. It is working now! Thnx again.
Re: Replace a word in a line except for the last char of the word?
by PhilHibbs (Hermit) on Mar 11, 2005 at 15:40 UTC
    You might be better replacing alternate spaces with &nbsp; since this has the same effect in HTML, takes up less space in the output, and is simpler code:

    s/  / &nbsp;/g;