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

Is there a regex that can convert all spaces in a row to nbsp's, save the first.

(EG: "Joe said   hello" --> "Joe said   hello")

Replies are listed 'Best First'.
Re: Converting multiple spaces to nbsp
by GrandFather (Saint) on Jun 17, 2005 at 04:37 UTC

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

    update: Fix code quoting for regex

    Perl is Huffman encoded by design.
      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.

        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.
Re: Converting multiple spaces to nbsp
by ikegami (Patriarch) on Jun 17, 2005 at 04:30 UTC

    A series of spaces preceeded by a space:

    s/(?<=\s)(\s+)/'&nbsp;' x length($1)/eg

    Update: Added needed parens around the \s+. doh!

      s/(?<=\s)(\s+)/'&nbsp;' x length($1)/eg

      You don't need to bother with the length and /e: just substituting one space at a time and letting the /g flag take care of the repetition works fine:

      s/(?<=\s)\s/&nbsp;/g

      Smylers

        oo! That's unexpected! I didn't realize that the previous substitution failed to affect (?<=...). s/(?<=\s)\s/&nbsp;/g had occured to me, but I had dismissed it. ++!

        local $\ = "\n"; local $_ = ' '; s/(?<=\s)\s/&nbsp;/g; print; print($_ eq ' &nbsp;&nbsp;&nbsp;' ? 'correct' : 'wrong'); __END__ &nbsp;&nbsp;&nbsp; correct