3

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

NoviceCodingGeek
  • 226
  • 4
  • 17
  • possible duplicate of [regex matching an open and close tag and a certain text patterns inside that tag](http://stackoverflow.com/questions/6368868/regex-matching-an-open-and-close-tag-and-a-certain-text-patterns-inside-that-tag) – NeronLeVelu Feb 25 '15 at 15:13

3 Answers3

4

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.

hwnd
  • 69,796
  • 4
  • 95
  • 132
4

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).

Amen Jlili
  • 1,884
  • 4
  • 28
  • 51
3

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 +.)

Community
  • 1
  • 1
tsnorri
  • 1,966
  • 5
  • 21
  • 29