Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Regular Expressions: Removing 'only' single spaces from a string

by BioBoy (Novice)
on Oct 20, 2005 at 18:23 UTC ( [id://501763]=perlquestion: print w/replies, xml ) Need Help??

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

Good day 2 you all. I am trying to take a string, and simply just remove only single spaces from it. For example, if you had the string:
"It is very cold now"
the spaces between 'is and very', as well as 'very and cold', should be removed, making the entire thing:
"It isverycold now"
Right now, I have this code:
$row_to_process =~ tr/\s{1}//;
, but it doesn't do what I want. Any suggestions?

Replies are listed 'Best First'.
Re: Regular Expressions: Removing 'only' single spaces from a string
by GrandFather (Saint) on Oct 20, 2005 at 18:28 UTC
    use warnings; use strict; my $str = "It is very very cold now"; $str =~ s/(?<! ) (?! )//g; print $str;

    Prints Itisvery  verycoldnow which I doubt is what you want, but is what you asked for.


    Perl is Huffman encoded by design.

      or you could use $str =~ s/\b \b//g;


      Perl is Huffman encoded by design.
        or you could use $str =~ s/\b \b//g;

        ...only if all the *non-space* characters are *word* characters:

        my $str = '@@@@ $$$ *** )))'; $str =~ s/\b \b//g; print $str;
        Thanks GrandFather. That almost worked 100%. I have some strings where the is no clear word boundary. Specifically, something like this:
        The boy to [ld his fat, her
        In that example, \b is failing to remove the space after to, and before '[', as well as the space after ',', and before her. Would I need to use \B as well?
Re: Regular Expressions: Removing 'only' single spaces from a string
by TedYoung (Deacon) on Oct 20, 2005 at 18:32 UTC

    Update: Ok the question was cleared up while I was writing this. Disreagard this post, the previous answers take care of it.

    First, you want to be using s/// for regexes, not tr///.

    $row_to_process =~ s/\s//g; # If you wanted to use tr/// (probably a bit faster here) $row_to_process =~ tr/ \n\t\r//d;

    Will remove all whitespace from a string. After this, your question is a little confusing. You talk about removing only single spaces. Why would the space between "It" and "is" and the space "cold" and "now" not be removed.

    Ted Young

    ($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)
Re: Regular Expressions: Removing 'only' single spaces from a string
by Not_a_Number (Prior) on Oct 20, 2005 at 19:34 UTC

    Probably not very efficient, but the best I can come up with at short notice:

    $str =~ s/(\S) (\S)/$1$2/g;

    Update:See Roy Johnson's comment above on Trix606's similar snippet. Code fixed for single spaces at start and end of string:

    s/(\S|^) (\S|$)/$1$2/g;
      what does the $1$2 mean? Doesn't the $ regular expression designate the end of the string?

        In the regular expression, yes it does. In the replacement expression $n is the n'th capture string in the regular expression. So for s/(x) (y)/$1$2)/ 'x y' gets replaced with 'xy' for example.


        Perl is Huffman encoded by design.
Re: Regular Expressions: Removing 'only' single spaces from a string
by BioBoy (Novice) on Oct 20, 2005 at 18:29 UTC
    EDIT: There should be many spaces between "It and is", as well as "cold and now". I'm not sure how to format this for this forum
Re: Regular Expressions: Removing 'only' single spaces from a string
by ioannis (Abbot) on Oct 20, 2005 at 22:59 UTC
    The OP asked to remove single spaces, not whitespaces. He did not mention about word-boundaries either; and even if he did, we don't know if the language he is using is covered under the \b concept of Perl. And therefore, to obey the bounds of the original request, here is another solution using negative lookahead.
    s/\ (?!\ )//gx ;
      It will remove the last space from any run of spaces. That is why you need both lookahead and lookbehind to make it work properly.

      Caution: Contents may have been coded under pressure.
      This solution worked perfectly. Now, do you think you could break it down for me? Forgive me, but I'm having a little trouble understanding it.

        Did it though? Consider:

        use warnings; use strict; my $str1= "It is very very cold now\n"; my $str2 = $str1; $str1 =~ s/(?<! ) (?! )//g; print $str1; $str2 =~ s/ (?! )//g; print $str2;

        which prints:

        Itisvery verycoldnow Itisvery verycoldnow

        Which string is correct? The (?<! ) is a zero width look back negative assertion: it matches if there isn't a space before the current space being matched. The (?! ) is a zero width look ahead negative assertion: it matches if there isn't a space after the current space being matched. Together these ensure that only single spaces are matched: only match a space that doesn't have a space before it and doesn't have a space after it.

        You should have a look at perlretut.


        Perl is Huffman encoded by design.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://501763]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-24 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found