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

So i've been trying to figure this out for 2 days now, say i am reading in a line from a file and assign it to a variable @lines. THen i'd like to manipulate that line, say for example take out all extra spaces for example. But i run into a problem when i get this situation: ($line[0] = "i need $money";)
open (FILE1 , "/stefan/cgi-bin/NoName01.txt") @lines = <FILE1>; $line[0] =~ s/" "/" "/g; print $lines[0];

the result would just be: i need
don't tell me to use single quotes, or put in \ infront of the $ sign. i can not because i am reading from a text file whose information is beyond my control. any ideas or help would be greatly appreciated, thanks in advance :)

Replies are listed 'Best First'.
Re: help! reading in special characters from file
by Joost (Canon) on Jun 01, 2007 at 19:15 UTC
    Don't just make up code when you post. Test it first to see if it really does what you think it does:
    $line[0] = 'i need $money'; # set variable directly, since I don't ha +ve your file. $line[0] =~ s/" "/" "/g; print $line[0]; # not $lines[0]
    prints
    i need $money
    Before you complain, it doesn't matter that I used single quotes here, since reading from a file does not interpolate anything.

    Also, s/"  "/" "/g does not remove spaces, except when you've got two spaces with double quotes around them. then it replaces that with a single space with quotes around it.

    update: please also use strict and warnings. It's not annoying if it really helps.

    update 2: just to stress the important point: reading data from a file / socket / other file-like handles does not interpolate any "special" characters..

    There are a few exceptions to this rule: reading in text mode (vs binary mode) will translate the line-separator to "\n" and using a character-encoding layer will translate the binary encoding to one perl can understand natively.

    In theory IO layers can do anything they want to the data read, but you wouldn't use them by accident, and they aren't enabled by default.

    The only time $, % and @ etcetera will be interpolated is when they're used in literal strings in perl code. That includes eval STRING, do and friends and (possibly relevant here) using the //e //ee etc regex modifiers (for the replacement part of a substitution).

    See also quote and quote-like operators and regex quote-like operators.

Re: help! reading in special characters from file
by GrandFather (Saint) on Jun 01, 2007 at 23:14 UTC

    Read I know what I mean. Why don't you? (although given your handle it's not clear you know what you mean)!

    Some general comments that don't address the problem that you hint at, but may help more in the long run:

    Always use strictures use strict; use warnings;.

    Use the three parameter open and check for success:

    my $filename = '/stefan/cgi-bin/NoName01.txt'; open (FILE1, '<', $filename) or die "Open failed for $filename: $!";

    Avoid slurping files. Use while (<FILE1>){...} to handle the file a "line" at a time.

    Read the regex documentation in perlretut and perlre. Regexen are a large part of what Perl is about and a knowledge of what they can do will stand you in good stead. Note that you can always go back and re-read the docs to refresh the details, but having an idea of what is there is essential knowledge for Perl programmers.


    DWIM is Perl's answer to Gödel
Re: help! reading in special characters from file
by derby (Abbot) on Jun 01, 2007 at 19:45 UTC

    If you just want to remove the extra spaces then use the \s+ construct:

    $lines[0] =~ s/\s+/ /g;
    The regex says substitute 1 or more spaces with a single space. (Note: you have $line[0] which I assume is a typo). Check out perlre for more info.

    -derby
      That will turn tabs into spaces (maybe not a bad thing, depending on the situation), and will turn the newline at the end into a space (usually a bad thing, depending on the situation).

      So one should decide exactly what is needed, depending on the situation:

      # pick one of: s/ +/ /g; # just reduce strings of consecutive spaces s/[ \xA0]+/ /g; # reduce and normalize space/nbsp strings s/[ \xA0\t]+/ /g; # include tabs as well s/\s+/ /g; # all kinds of whitespace, including newlines