0

I have a text like:

This patch requires:

Patch 1.10-1
Patch 1.11-2

Notes:

I want to extract

Patch 1.10-1
Patch 1.11-2

with the following regex:

This patch requires\:[\r\n](.*)[\r\n]Notes\:

But nothing is matched.

Why ?

revo
  • 43,830
  • 14
  • 67
  • 109
Snake Eyes
  • 14,643
  • 31
  • 97
  • 188

3 Answers3

1

For the sake of alternative solutions:

^\QThis patch requires:\E\R+
\K
(?:^Patch.+\R)+


This says:
^\QThis patch requires:\E     # match "This patch requires:" in one line and nothing else
\R+                           # match empty lines + newlines
\K                            # "Forget" what's left
(?:^Patch.+\R)+               # match lines that start with "Patch"

In PHP:

<?php

$regex = '~
    ^\QThis patch requires:\E\R+
    \K
    (?:^Patch.+\R)+
         ~xm';

if (preg_match_all($regex, $your_string_here, $matches)) {
    // do sth. with matches
}

See a demo on regex101.com (and mind the verbose and multiline modifier!).

Jan
  • 38,539
  • 8
  • 41
  • 69
0

What about (?<=[\r\n])(.+)(?=[\r\n])

Demo

Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
0

But nothing is matched.

DOT . doesn't match newline characters so .* doesn't go beyond one line. For that you need to set DOTALL s modifier on or try an alternative [\s\S] (which literally means any character without any exception).

preg_match('~This patch requires:\s*([\s\S]*?)\s*^Notes:~m', $text, $matches);
echo $matches[1];

Note: don't use greedy-dot (.*) if multiple matches are going to occur instead go lazy .*?

By the way this is supposed to be the most efficient regex you may come across:

This patch requires:\s+((?:(?!\s*^Notes:).*\R)*)

Live demo

revo
  • 43,830
  • 14
  • 67
  • 109