Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>With the entire file in a scalar, write your pattern so it captures the lines before and after <code>line3</code>. The <a href="http://perldoc.perl.org/perlre.html#Modifiers" rel="nofollow noreferrer"><code>/m</code> modifier</a> is especially useful:</p> <blockquote> <p>Treat string as multiple lines. That is, change <code>^</code> and <code>$</code> from matching the start or end of the string to matching the start or end of any line anywhere within the string.</p> </blockquote> <p>The patterns below use the <code>/x</code> modifier that lets us add whitespace to make them look like what they're matching.</p> <p>For example:</p> <pre><code>#! /usr/bin/perl my $data = do { local $/; &lt;DATA&gt; }; my $pattern = qr/ ^(.+\n) ^line3\n ^(.+\n) /mx; if ($data =~ /$pattern/) { print $1, $2; } else { print "no match\n"; } __DATA__ line1 line2 line3 line4 line5 </code></pre> <p>Output:</p> <pre>line2 line4</pre> <p>Remember that <code>$</code> is an assertion: it doesn't consume any characters, so you have to match newline with a literal <code>\n</code> pattern.</p> <p>Also note that the pattern above lacks generality. It works fine for a line somewhere in the middle, but it will fail if you change <code>line3</code> to <code>line1</code> or <code>line5</code>.</p> <p>For the <code>line1</code> case, you could make the previous line optional with a <code>?</code> quantifier:</p> <pre><code>my $pattern = qr/ ^(.+\n)? ^line1\n ^(.+\n) /mx; </code></pre> <p>As expected, this produces output of</p> <pre>line2</pre> <p>But trying the same fix for the <code>line5</code> case</p> <pre><code>my $pattern = qr/ ^(.+\n)? ^line5\n ^(.+\n)? /mx; </code></pre> <p>gives</p> <pre>no match</pre> <p>This is because after the final newline in the file (the one following <code>line5</code>), <code>^</code> has nowhere to match, but changing the pattern to</p> <pre><code>my $pattern = qr/ ^(.+\n)? ^line5\n (^.+\n)? /mx; </code></pre> <p>outputs</p> <pre>line4</pre> <p>We might stop here, but the asymmetry in the pattern is unpleasing. Why did work for one case and not for the other? With <code>line1</code>, <code>^</code> matches the beginning of <code>$data</code> and then matches nothing for <code>(.+\n)?</code>.</p> <p><strong>Remember:</strong> patterns quantified with <code>?</code> or <code>*</code> <em>always</em> succeed because they're semantically the same as</p> <ul> <li>zero times or one time</li> <li>zero or more times</li> </ul> <p>respectively, and <em>anything</em> can match zero times:</p> <pre>$ perl -le 'print scalar "abc" =~ /(?!)*/' 1</pre> <p>Although I can't think of a time I've ever seen it used this way, an <code>{m,n}</code> quantifier where <em>m</em> is zero, <em>e.g.</em>,</p> <ul> <li>{0,100}</li> <li>{0,}</li> <li>{0}</li> </ul> <p>will always succeed because <em>m</em> is the minimum number of repetitions. The <code>{0}</code> quantifier is a pathological case included for completeness.</p> <p>All that was to show we more or less got lucky with the <code>line1</code> case. <code>^</code> matched the very beginning, the <code>?</code>-quantified pattern matched nothing, and then the next <code>^</code> also matched the very beginning of <code>$data</code>.</p> <p>Restoring symmetry makes a cleaner pattern:</p> <pre><code>my $pattern = qr/ (^.+\n)? ^line5\n (^.+\n)? /mx; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload