in reply to Converting multiple spaces to nbsp

s/\s(\s+)/" " . (" " x length ($1))/ge

use strict; use warnings; my $str = "Joe said hello"; print "\"$str\" --> \""; $str =~ s/\s(\s+)/" " . (" " x length ($1))/ge; print $str . "\"\n"; "Joe said hello" --> "Joe said   hello"
update: Fix code quoting for regex

Perl is Huffman encoded by design.

Replies are listed 'Best First'.
Re^2: Converting multiple spaces to nbsp
by eastcoastcoder (Sexton) on Jun 17, 2005 at 04:42 UTC
    Wow, that was quick!

    Two points:

    • 1) I only want space, not tabs or new lines - so shouldn't the \s be replaced with " "?
    • 2) Is there a difference between inkgmi's and GrandFather's entry?

    PS I thought executed regexs are experimental (so says the man page) - is there a problem with them?

      I only want space, not tabs or new lines

      Then yes, substitute "\s" with "" or "\040". Keep in mind that HTML doesn't know the difference between spaces, tabs and newlines.

      Is there a difference between inkgmi's and GrandFather's entry?

      I think mine is a teeny bit faster. (One less character to add to $1, one less operation in building the replacement string, one less character to replace.)

      I thought executed regexs are experimental

      Just
      (?{ code }),
      (??{ code }),
      (?>pattern) and
      (?(condition)yes-pattern|no-pattern),
      none of which were used here. /e has been around for quite some time and is reliable.

        I think you are right about the execution speed. It would be interesting to benchmark.

        I would like to think that my solution is slightly easier to understand, but I consider that I am writing toddler Perl (up from baby Perl) and still have a lot to learn. And I have learned from your answer, thank you.


        Perl is Huffman encoded by design.
        I thought executed regexs are experimental
        /e doesn't produce an executed regex! Instead, it tells perl that the substitution part is to be parsed and treated and executed as perl code. Furthermore, there's no eval taking place, the code is parsed and compiled at compile time.

        Note: LSH = regex, RHS = substite

        All those features that ikegami lists as experimental, are to be used in the regex part. But /e isn't.

        well it appears it's the slower of the two...
        #!/usr/bin/perl use Benchmark qw(cmpthese); my $test_text = q|Wow, that was quick!<br/> Two points:<br/> 1) I only want space, not tabs or new lines - so shouldn't the \s be + replaced with " "? <br/> 2) Is there a difference between inkgmi's and GrandFather's entry? <b +r/> PS I thought executed regexs are experimental (so says the man page) - + is there a problem with them?<br/> |; my $working_var; my $count = 1000000; cmpthese($count, { 'grandfather' => sub {$working_var = $test_text; $working_var =~ s +/ ( +)/" " . ("&nbsp;" x length ($1))/ge}, 'ikegami' => sub {$working_var = $test_text; $working_var =~ s +/(?<= )( )/'&nbsp;' x length($1)/eg} }); __OUTPUT__ Benchmark: timing 1000000 iterations of grandfather, ikegami... grandfather: 31 wallclock secs (31.01 usr + 0.00 sys = 31.01 CPU) @ 3 +2252.86/s (n=1000000) ikegami: 52 wallclock secs (51.26 usr + 0.00 sys = 51.26 CPU) @ 19 +506.87/s (n=1000000) Rate ikegami grandfather ikegami 19507/s -- -40% grandfather 32253/s 65% --
        Personlly I'd go with GrandFather's solution even if it were the slower, on the grounds I think it'd be more readable to more people.
        ---
        my name's not Keith, and I'm not reasonable.

      The /e modifier (evaluation) is not experimental. You're probably thinking of (?{...}) and (??{....}) which are considered experimental. Actually, the've proven to be fairly stable over the last few Perl releases, other than having a few kinks worked out.


      Dave

      Yes, substitute spaces for the \s in either version.

      GrandFather's solution comes with an example :-)


      Perl is Huffman encoded by design.