Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

regex: match multiple lines until a line contains

Tags:

regex

I have the following string:

foo.a = [10
20
30
40];

foo.b = 'foobar';

I am using the foo\.[ab]\s*= regex.

I try to match all the lines that follow until a line contains a certain character.

The first match should cover everything except of the last line, because that line contains an equal sign. I tried a lot of things with (negative) lookahead, but I can't figure it out.

like image 940
Simon Hänisch Avatar asked Feb 12 '16 15:02

Simon Hänisch


People also ask

What does \+ mean in regex?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" .

What is regex multiline mode?

Multiline option, or the m inline option, enables the regular expression engine to handle an input string that consists of multiple lines. It changes the interpretation of the ^ and $ language elements so that they match the beginning and end of a line, instead of the beginning and end of the input string.

How do you match line breaks in regex?

If you want to indicate a line break when you construct your RegEx, use the sequence “\r\n”. Whether or not you will have line breaks in your expression depends on what you are trying to match. Line breaks can be useful “anchors” that define where some pattern occurs in relation to the beginning or end of a line.

How do you match everything including newline regex?

If you want . to match really everything, including newlines, you need to enable “dot-matches-all” mode in your regex engine of choice (for example, add re. DOTALL flag in Python, or /s in PCRE.


2 Answers

You need a positive lookahead.

foo\.[ab][\s\S]*?(?=\n.*?=|$)
  • [\s\S]*? matches lazily any character
  • (?=\n.*?=|$) until a newline containing an = is ahead or $ end.

See demo at regex101

like image 108
bobble bubble Avatar answered Oct 12 '22 14:10

bobble bubble


Variation 1

foo\.[ab]\s*=[\s\S]*?(?=foo\.[ab]\s*=)

It matches what you want up until another foo.a = or foo.b = using a positive lookahead.

Demo: https://regex101.com/r/xV9wL4/2

Variation 2

(foo\.[ab]\s*=)[\s\S]*?(?=(?1))

This works the same as above but using a capturing group and a reference to that capturing group (by (?1)) to simplify it down

Demo: https://regex101.com/r/xV9wL4/3

like image 22
RedLaser Avatar answered Oct 12 '22 14:10

RedLaser