membersound
membersound

Reputation: 86875

Regex lookbehind with linebreaks?

I'm trying to extract content bewteen boundaries using lookahead/behind like this:

Filename: myfile.txt
Message: myMessage
Time:...

I want to extract what's between the filename and the time using regex:

(?<=.txt).*(?=Time)

But it does not work as linebreaks are not taken. What can I change to match?

Upvotes: 0

Views: 2683

Answers (2)

ikegami
ikegami

Reputation: 386541

First, you forgot to escape the . in .txt.

/(?<=\.txt).*(?=Time)/

Secondly, you don't actually capture ("extract") anything.

/(?<=\.txt)(.*)(?=Time)/

Then you need to tell Perl that . should match every character, not every character except newlines.

/(?<=\.txt)(.*)(?=Time)/s

And there you go. You could improve it a little by only matching from the start to the end of a line:

/(?<=\.txt\n)(.*)^(?=Time)/sm

Btw, there doesn't seem to be any reason to use lookarounds in this case.

Upvotes: 4

user1919238
user1919238

Reputation:

In order to make . match a newline, you need to enable the /s, which makes the entire string be treated as a single line.

In addition, you probably should not use look-arounds for this. Generally, they should only be used when you want to get overlapping matches. They can produce unexpected results when used to simply get part of a match.

The standard way to get a part of a match is to use capturing subgroups:

if (/\.txt(.*?)Time/s)
{
   print "The between portion is:\n$1";
}

Upvotes: 0

Related Questions