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

Greetings. I've always assumed that when using the <stdin> operator, whatever is passed in will contain a carriage return (thus the utility of the chomp function). So I guess I'm perplexed that the following code seems to work...
while(($num=<stdin>)!~/^999$/){ ... }
My assumption would be that the above regex would always prove false due to the input always being something like '999\n'. I know there is probably a good explanation of this and it has to do with how perl treats scalars...hopefully your wisdom will provide me with needed insight into the workings of this mysterious language. Thanks, Jason

Replies are listed 'Best First'.
Re: String Newline Question
by Juerd (Abbot) on Mar 23, 2002 at 22:22 UTC

    In a regex, $ does not mean "end of string". It means "end of line", which is just before \n or the end of the string (whichever comes first). If you want to match the null string at the end of the string, use \z.

    $_ = "foo\n"; /^foo$/; # true /^foo\z/; # false /^foo\n$/; # true /^foo\n\z/; # true
    $ behaves like (?=\z|\n).

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

        No, it behaves like (?=\n?\z). Yours would match any embedded newline.

        Oops, I was describing the situation for when /m (or (?m:)) is in effect, which was not the case.

        Update - Hm, even if that were the case, it would be wrong. It would behave like (?=\n\z?|\z).

        U28geW91IGNhbiBhbGwgcm90MTMgY
        W5kIHBhY2soKS4gQnV0IGRvIHlvdS
        ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
        geW91IHNlZSBpdD8gIC0tIEp1ZXJk
        

Re: String Newline Question
by insensate (Hermit) on Mar 23, 2002 at 22:21 UTC
    UPDATE: sorry..got stiffed by html... I've always assumed that when using the operator <stdin>, whatever is...(my bad)
Re: String Newline Question
by Parham (Friar) on Mar 24, 2002 at 16:46 UTC
    it wasn't part of the real question, nonetheless it's another good point:

    if you had a string:

    $string = "something\n0999\nsomething\n";

    and you matched against it ending with 999 with the /m option, it would also work. For example using this regex would yield a pass for the regex:

    if ($string =~ /999$/m) { print "pass"; }

    /m just treats the $string as a multi-line string and if it finds 999 at the end of any line in $string (remember $ means before the newline) then the regex would still work. I thought i'd just throw that in cuz it was useful :).