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

Hi,
i use following command:
$str =~ s/ / /g;
1.string: whitespace
2.string: a tab

Are there special commands/signs for tab/whitespace in perl? whitespace is not a problem, but tab. I want be sure that tab is substituted.
Do you know a better way ?
Thanks for your help.
star7

Replies are listed 'Best First'.
Re: whitespaces replace with tabs - help needed...
by cfreak (Chaplain) on Aug 14, 2003 at 13:38 UTC
Re: whitespaces replace with tabs - help needed...
by bm (Hermit) on Aug 14, 2003 at 15:23 UTC
    Why re-invent the wheel?
    use Text::Tabs; my $tabstop = 4; @lines_with_tabs = unexpand(@lines_without_tabs);
    This module is part of (my) core Perl.
    --
    bm

      Of course, this doesn't actually substitute each space character with a tab, as the original poster claims to want (whether that's what s/he really wants is an open question :)...

      Also, the my declaration creates a new lexical variable called $tabstop, which doesn't have any effect on the module's behavior. Instead, you can just get rid of the my since $Text::Tabs::tabstop is exported by the module.

      -- Mike

      --
      XML::Simpler does not require XML::Parser or a SAX parser. It does require File::Slurp.
      -- grantm, perldoc XML::Simpler

      I know we are discussing a Perl solution, but for something like this (and assuming you are using some flavor of linux) you can simply use the existing "expand" utility...
Re: whitespaces replace with tabs - help needed...
by esh (Pilgrim) on Aug 14, 2003 at 14:44 UTC

    Are you sure you don't want to replace whitespace with tabs so that the resulting text looks the same on a device that supports tabs?

    This would require a little more calculation than just replacing every single whitespace character with a single tab character, but is certainly something that folks here could help with.

    Also, you should realize that \s matches newlines. This may not be what you intended.

    -- Eric Hammond

Re: whitespaces replace with tabs - help needed...
by monktim (Friar) on Aug 14, 2003 at 13:38 UTC

      That only matches a space. The term 'whitespace' is much broader than a space--it includes things like newlines, tabs, etc. You want to match using \s, which matches any whitespace character.

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      Note: All code is untested, unless otherwise stated

        hardburn is right about what constitutes a whitespace, but I suspect that star7 may not be using the term correctly.
        I'm also confused, star7, when you say tabs are the problem. You seem to be putting tabs into your document. If they are the problem, wouldn't you be trying to remove them?

        $str =~ s/\t/ /g;

        Replacing each tab with a space. (not whitespace)

        -ted-

        Thanks. I realized that right after I clicked the submit button. Then I noticed someone else posted the s/\s/\t/g so I didn't bother updating my node. I'm new here, what is the policy? Should I fix my nodes even when someone beats me to the punch?
      That*s the way i like it :)

      i wrote following code:
      LINE: while(<FILE>) { chomp($_); $_=~ s/ +/\t/s; print OUTPUT "$_\n"; # $_ =~ s/^(d{6})\t(d{2}):(d{2})/$1 $2:$3/g; }; close(FILE); close(OUTPUT);

      (maybe i have to use the option e)
      What i want:
      1. replace one or more spaces with a tab
      2. see #comment: in the line (-> $_ ) replace first tab with a space

      Maybe you are more sage as i.
      can you help me to adjust this code.
      Thanks.
      star7

        I'm a new user of this site and first time poster. Forgive me if I error ;-)

        You said:

        1. replace one or more spaces with a tab

        2. see #comment: in the line (-> $_ ) replace first tab with a space

        But 1 says the reverse of what 2 says, if I'm reading it correctly.

        So, trying to answer 1: s/\s+/\t/does what you want, once, on the first group of white space characters found.

        And, again, trying to answer 2: s/\t/ /will do the trick, for the first tab found in the input, converting it to a space.

        If you want these to work on all groups of whitespace or on all tabs found on input, add the 'g' modifier, as in your commented example:

        s/\s+/\t/g s/\t/ /g

        Following are some comments regarding whitespace, for those interested, and on the code snippet provided by star7.

        Hi,

        you may want to take a look at tr// (`translate'), especially the `s' modifier. This will replace multiple duplicated characters with one instance of the required character.

        For example, in your line

        $_=~s/ +/\t/s;,

        (the $_ isn't really necessary here) you could have

        tr/ /\t/s;. I understand it's quite a bit more efficient.