title: Perl regex matching numbers
body: <p>I'm working on a Perl assignment. One of the requirements is to match all integer and float numbers except those in comments or strings (double or single quoted).</p>
  
  <p>Here is my assumption:</p>
  
  <ul>
  <li>Optional sign, integer, and fraction.  </li>
  <li>If the integer part is omitted, the fraction is mandatory.  </li>
  <li>If the fraction part is omitted, the decimal dot must be omitted.</li>
  </ul>
  
  <p>And here is the regex I found.</p>
  
  <pre><code>([-+]?([0-9]+(\.[0-9]+)?|\.[0-9]+))
  </code></pre>
  
  <p>Here is my block of code, I had trouble to exclude numbers in comments and strings so I remove all comments and strings first. I also split lines into words, I believe this should be easier. But I also believe this should not be necessary.</p>
  
  <pre><code>while (&lt;$IN_FILE&gt;) {
      s/^(#[^!]+$)//;            # remove whole line comments
      s{(^[^#]+?)(#[^/]+$)}{$1}; # remove inline comments
      s/('.*?'|".*?")//g;        # remove all single line strings
      push @words, split;        # split line into words
    }
  
    foreach my $item (&lt;@words&gt;) {
      push @numbers, $1 if $item =~ /([-+]?([0-9]+(\.[0-9]+)?|\.[0-9]+))/;
    }
  </code></pre>
  
  <p>It worked ok but failed to match array index like the <code>0</code> in <code>ARGV[0]</code>.</p>
  
  <p>So I need some help to improve my code, it would be nice if I don't have to remove comments, strings first, don't need to split lines into words, and of course match all the numbers not in comments and strings.</p>
  
  <p>Simple input</p>
  
  <pre><code># Comment 1
  my $time = &lt;STDIN&gt;;
  chomp $time;
     #now write input to STDOUT
  print $time . "\n";
  my $pi = 3.1415926;
  my $test = -3.22;
  my $t = +0.01;
  my $range = (8..11);
  if $ARGV[0];
  sub sample2 {
     print "true or false";
     return 3 + 4 eq "7"; # true or false
  }
  </code></pre>
  
  <p>Here is the output from my code it missed <code>0</code> in <code>ARGV[0]</code> and <code>11</code> in <code>(8..11)</code>. I won't be surprised if it misses more.</p>
  
  <pre><code>[Numbers]
  3.1415926
  -3.22
  +0.01
  8
  2
  3
  4
  </code></pre>