NoviceCodingGeek
NoviceCodingGeek

Reputation: 226

Regex matches only once

I have a regex that should rewrite [img]foo.bar[/img] to <img src=foo.bar> and in fact, it does. The problem comes in when I have two or more of those [img]url.ext[/img] in the string. Instead of matching each one separately, it matches the first [img] and the last [/img] and leaves the urls and tags in the middle as part of the src. My php code is $newstring = preg_replace('%\[img\](.+)\[/img\]%', '<img src=${1}>', $string);

a working example is https://www.regex101.com/r/mJ9sM0/1

Upvotes: 3

Views: 7464

Answers (3)

hwnd
hwnd

Reputation: 70732

The + operator is greedy by default, you need to use +? for a non-greedy match.

$str = preg_replace('~\[img]\s*(.+?)\s*\[/img]~i', '<img src="$1">', $str);

Note: I propose the above — recommending the i flag for case insensitive matching.

Upvotes: 4

Amen Jlili
Amen Jlili

Reputation: 1944

Use +? instead of + for non-greedy match.

\[img\](.+?)\[/img\]

Demo https://www.regex101.com/r/zW9zJ0/1

+ Will match one of more occurrence. Combined with ?, it will match as least as possible (lazy).

Upvotes: 4

tsnorri
tsnorri

Reputation: 2097

Regular expressions are greedy by default. Try with non-greedy regex, i.e.

preg_replace('%\[img\](.+?)\[/img\]%', '<img src=${1}>', $string);

(Note the ? after the +.)

Upvotes: 3

Related Questions