http://www.perlmonks.org?node_id=641566

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

I have been digging and digging in the archives here and in Programming Perl and in Mastering Regular Expressions to no avail. I am parsing a file into a list and the foreach-ing through that list. I'm trying to find out if any lines contains only "1\n" (Which is what several hundred lines contain.) I am using the following code:
$linenumber=1; foreach $line(@fileData) { $linenumber=$linenumber+1; if ($line =~ m/^1$/) { print "$linenumber\n"; } }
What am I doing wrong!?!

Replies are listed 'Best First'.
Re: Help with regex
by FunkyMonk (Chancellor) on Sep 28, 2007 at 16:33 UTC
    Adding some test data:
    use List::Util 'shuffle'; my @fileData = shuffle map { "$_\n" } 1 .. 20, (1) x 5; my $linenumber=1; foreach my $line(@fileData) { $linenumber=$linenumber+1; if ($line =~ m/^1$/) { print "$linenumber\n"; } }

    Output:

    6 7 8 16 17 25

    Are you sure you're reading your data correctly?

      My data must be something other than what I think it is. I'll revisit it. Thanks.
        You might try m/^1\s*$/ for your regular expression.
        -- gam3
        A picture is worth a thousand words, but takes 200K.

        How are you populating your @fileData array? Is there any reason not to iterate over the filehandle directly?

        use strict; use warnings; my $infile = 'whatever'; open my $fh, '<', $infile or die "Couldn't open '$infile' for read: $! +\n"; while ( my $line = <$fh> ) { print "$.\n" if $line =~ m/^1$/; }
Re: Help with regex
by toolic (Bishop) on Sep 28, 2007 at 16:32 UTC
    Why do you think you are doing something wrong? Please provide a small sample of your input file, the corresponding output, and what you expect the output to be.

    When I run your code with my own input, the output I get is the line number plus 1 of the lines which just contain 1\n. To get the actual line number:

    $linenumber=1; foreach $line(@fileData) { if ($line =~ m/^1$/) { print "$linenumber\n"; } $linenumber++; }
    Update: You could also use the special variable $. instead of $linenumber

    tinita is more precise. $. is used with filehandles.

      You could also use the special variable $. instead of $linenumber.
      not while looping over an array, only when reading lines from a filehandle.
      Some say premature optimization is the root of all programming evils (but then they must not have ever used COBOL). Overly concise code is generally a bad idea in production, too. However, I think that without hurting clarity it's always better to remove code to fix a problem rather than moving it around. This can often be done simply for off-by-one errors.
      foreach $line ( @fileData ) { $linenumber++; if ( $line =~ m/^1$/) { print "$linenumber\n"; } }
      Then there's the issue of idiomatic usage, which may or may not lead one to use $_, implicit matching against $_, or 'for' instead of 'foreach', depending one their views. This leads to code about as legible as the previous for many Perl coders, but I think it's fair to call it a matter of preference.
      for ( @fileData ) { $linenumber++; if ( m/^1$/ ) { print "$linenumber\n"; } }
      Which shouldn't be confused at all with golf, which does hinder legibility somewhat.
      $l++,/^1$/&&print$l.$/for@f;
Re: Help with regex
by throop (Chaplain) on Sep 28, 2007 at 19:50 UTC
    I suspect you are forgetting to chomp your input.

    Have you used the debugger on this script, and really looked at what each each $line looks like?

    throop

      Given that the OP is searching for strings that end with a newline, I doubt chomping is going to help!