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

Hello
I want to remove all the blank lines and the lines with messages between "", but my code just remove the messages and leave the blank lines, what's wrong?
while(defined($line = <IN>)) { if($line =~ /(^\s*)(\"[^*]*?\")$/g) {next;}; #Blow off blank lines chomp($line); }

Merci

Replies are listed 'Best First'.
Re: Blow off blank line and lines with messages
by davorg (Chancellor) on Sep 20, 2002 at 14:58 UTC
    while (<IN>) { next unless /\S/; # ignore blank lines next if /^\s*".*"\s*$/; # ignore message lines # do stuff }
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Blow off blank line and lines with messages
by Aristotle (Chancellor) on Sep 20, 2002 at 15:04 UTC
    The message part of your regex isn't optional. Append a ? to make it so. Your use of the /g modifier there was misplaced - since you're already anchoring at the front and end of the string, the pattern can't match multiple times in the first place. Relying on the $_ variable can also make your code much shorter.
    while(<IN>) { next if /^(\s*)("[^"]+")?$/; chomp; }
    Update: [^*"] -> [^"]. Thanks sauoq.

    Makeshifts last the longest.

Re: Blow off blank line and lines with messages
by sauoq (Abbot) on Sep 20, 2002 at 16:09 UTC
    if($line =~ /(^\s*)(\"[^*]*?\")$/g) {next;};

    In addition to what others have said, the "message" piece of that has a typo. The character class, [^*] will match anything but an asterisk. I'm pretty sure you intended for that to be [^"] which will match anything but a double quote. Once you make that change, you can remove the ? and just greedily match.

    Some of what you are doing is simply unnessecary. Since you aren't looking for more than one match, your /g modifier is unneeded. Also, quotations aren't regular expression metacharacters and they don't require backslashes. You don't need to capture anything; you only need to group the "message" part together and you can use (?: ... ) to do that. Finally, you are anchoring to the end of the line and that is probably not what you want as it'll miss lines with "messages" that have spaces after the message. (Actually, that part of your requirements isn't well specified. You might want to anchor it afterall, or you might want to allow \s* before the anchor, or you might not want to anchor at all. The second choice is probably the safest bet.)

    Making these changes and making the "message" part optional as Aristotle pointed out and rearranging for readability like davorg did yields:

    next if ($line =~ /^\s*(?:"[^"]*")?\s*/);
    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Blow off blank line and lines with messages
by swiftone (Curate) on Sep 20, 2002 at 15:00 UTC
    Your regex only skips lines that have "" messages. If you want to skip blank lines, add  next if $line =~ /^\s*$/;

    The chomp will remove the newline of a blankline, but leave the line itself. (You aren't doing anything with any of the lines here, so I'm assuming you're showing simplified code)

    Besides, a "blank line" may be one that has spaces in it.