Ilijanovic
Ilijanovic

Reputation: 14904

Regex cant limit search range

I have following problem:

I have a pattern like this:

/(?<=template=")(.*?)(.*\/)/gm 

And an text like this:

template="test/widgets/glasgow.phtml"}}

My regex should search for the path infront of my file, i need to cut it out so that it will look at the end like this:

   template="glasgow.phtml"}}

That works fine but the problem is that i have sometimes an text that looks like this:

block="core/template" template="test/widgets/getcallus.phtml"}}</p>

It cuts everything out till the </.

This is getting cutted out:

test/widgets/getcallus.phtml"}}</

Instead of:

test/widgets/

I have tried to limit the end with $ but it doesnt do nothing.

I am testing it on regexr.com

https://regexr.com/50hi2

Upvotes: 2

Views: 109

Answers (2)

David Amar
David Amar

Reputation: 257

Be careful with (.*?)(.*\/)

This pattern corresponds to a REDOS vulnerability. (There are 2^n ways to read the n chars before the last /...

To keep a regex closed to yours, you can use /(?<=template=")([^"]*?\/)*([^"]*)"/

([^"]*?\/)* reads as many blocks "non / nor " chars followed by /" as possible.

https://regex101.com/r/SMSv5R/2

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626728

You may use the following pattern:

template="\K[^"\/]*\/[^"\/]*\/

See the regex demo. In PHP, you may get rid of backslashes if you specify another regex delimiter:

$regex = '~template="\K[^"/]*/[^"/]*/~';

Details

  • template=" - literal text
  • \K - match reset operator
  • [^"\/]* - 0 or more chars other than / and "
  • \/ - a / char
  • [^"\/]* - 0 or more chars other than / and "
  • \/ - a / char

It is equal to template="\K(?:[^"\/]*\/){2}, where (?:...){2} repeats the non-capturing group sequence of patterns twice.

Upvotes: 2

Related Questions