28

I have this data in a LONGTEXT column (so the line breaks are retained):

Paragraph one
Paragraph two
Paragraph three
Paragraph four

I'm trying to match paragraph 1 through 3. I'm using this code:

preg_match('/Para(.*)three/', $row['file'], $m);

This returns nothing. If I try to work just within the first line of the paragraph, by matching:

preg_match('/Para(.*)one/', $row['file'], $m);

Then the code works and I get the proper string returned. What am I doing wrong here?

Norse
  • 5,304
  • 13
  • 47
  • 84

4 Answers4

61

Use s modifier.

preg_match('/Para(.*)three/s', $row['file'], $m);

http://php.net/manual/en/reference.pcre.pattern.modifiers.php

Tasso Evangelista
  • 1,469
  • 1
  • 14
  • 20
  • 2
    Warning: the `/s` modifier is greedy. If there is more than one 'three' in the text, the match will include all text until the last occurence. use `/sU` to prevent this (note the upper case U). – Frank Forte Feb 05 '18 at 19:40
  • 2
    @FrankForte not really a modifier issue: the `*` repetition is greedy per se. A better approach is to put a question mark to make it lazy: `/Para(.*?)three/s`. Also, the `/U` modifier not cancel greedyness, but invert it: `*` becomes lazy and `*?` becomes greedy. Is not a problem on OP code, but it can trigger weird errors in a more complex regular expression. – Tasso Evangelista Feb 06 '18 at 20:17
12

Add the multi-line modifier.

Eg:

preg_match('/Para(.*)three/m', $row['file'], $m)
temporalslide
  • 937
  • 7
  • 9
  • 9
    For anybody wondering about the difference between this and the accepted answer (`s` modifier), the `s` modifier makes `.` match newlines as well as all other characters (by default it excludes them), whereas `m` controls how `^` and `$` match; forcing them to only match the start and end of the whole string (almost - see also `D`) as opposed to the start and end of each line. – Dave Mar 08 '16 at 15:42
4

Try setting the regex to dot-all (the extra 's' parameter at the end), so it includes line breaks:

preg_match('/Para(.*)three/s', $row['file'], $m);
Jen
  • 428
  • 5
  • 15
0

If you don't like / at the start and and, use T-Regx

$m = Pattern::of('Para(.*)three')->match($row['file'])->first();
Danon
  • 1,793
  • 14
  • 28