Regex - Capture multiline pattern - the shortest match

Viewed 48

My test result in regexr dot com

I'm trying to capture the shortest match in multiline text, and stop check if the beginning pattern appears again before the whole pattern is found.

Pattern with issue:

    test2(.|\n)*?test4

Input:

    1       test1
    2       test2
    5       test5
    6       test1
    7       test2
    8       test3
    9       test4
    10      test5
    11      test1
    12      test2
    13      test3
    14      test4
    15      test5

Expected 2 result:
First: line 7 till line 9
Second: line 12 till line 14

Actual (unwanted) result:
First: line 2 till line 9
Second: line 12 till line 14

1 Answers

The (.|\n)*? is non greedy, but it can also match any characters including any form of the test string.

What you might do is limit the accepted test string by allowing only digits 2, 3 or 4 and make the non capture group non greedy to get the "shortest" match.

test2(?:\n.*test[234])*?\n.*test4

The pattern matches:

  • test2 match literally
  • (?: Non capture group to repeat as a whole
    • \n.*test[234] Match a newline and in the line test followed by a digit 2, 3 or 4
  • )*? Close the non capture group and optionally repeat non greedy
  • \n.*test4 Match a newline and a line that matches test4

See a regex demo.

Related