title: Perl regex to match up to but not including optional end-token
body: <p>I am trying to efficiently match lines up to but not including an optional end-token.</p>
  
  <pre><code>/(.*)(?:$tok)?/
  </code></pre>
  
  <p>doesn't work. The end-token is optional, hence the final ?, but then the first group
  greedily captures it.</p>
  
  <pre><code>/(.*?)(?:$tok)?/
  </code></pre>
  
  <p>also doesn't work: the first group matches a zero-length string</p>
  
  <p>The best I can do so far is</p>
  
  <pre><code>my $tok = 'end';
  while (&lt;&gt;) {
      my ($line) = /
         (?|             # 'branch reset'
             (.*)$tok    # either a line terminated with the end token
           |             # or
             (.*)        # the whole line
         )               # end branch reset group
      /x;
      print $line, "\n";
  }
  </code></pre>
  
  <p>This works, but strikes me as inefficient. The regex engine has to parse the line twice, which is what I was trying to avoid.</p>
  
  <p>I'm aware the problem as stated would be better solved with index():</p>
  
  <pre><code>my $i = index($_, $end);
  $line = $i &lt; 0 ? $_ : substr $_, 0, $i;
  </code></pre>
  
  <p>but I need to do other processing of the line making a regex desirable - and in any event, I see this as a learning opportunity ;-)</p>