1

I have an input string that looks something like this:

$txt = '!1 aaa !2 bb bb !5 cc cc cc !4 dd';

In other words, I have a number of fields, each starting with an exclamation mark and a digit.

It want to turn this into something like this:

<div class="x1">aaa</div>
<div class="x2">bb bb</div>
<div class="x5">cc cc cc</div>
<div class="x4">dd</div>

where the div class derives from the digit following the exclamation mark in the input string.

I've tried this PHP command:

preg_replace("/!([0-9]) (.*) !/U", "<div class=\"x\\1\">\\2</div>\n!", $txt)

But that produces this output:

<div class="x1">aaa</div>
!2 bb bb <div class="x5">cc cc cc</div>
!4 dd

It's obvious that the last field (!4 dd) is not matched, since it doesn't have a final !. And I assume that the second field (!2 bb bb) is not matched because its initial ! actually comes from the replacement of the first string.

So, I guess I know why it isn't working, but I can't work out how to do this correctly.

oz1cz
  • 5,504
  • 6
  • 38
  • 58

1 Answers1

2

You can use

echo preg_replace('~!(\d+)\s*(.*?)\s*(?=!\d|$)~s', "<div class=\"x\$1\">\$2</div>\n", $txt);

See the regex demo and the PHP demo. Details:

  • ! - a ! char
  • (\d+) - Group 1: one or more digits
  • \s* - zero or more whitespaces
  • (.*?) - Group 2: any zero or more chars as few as possible
  • \s* - zero or more whitespaces
  • (?=!\d|$) - a positive lookahead that matches a location that is immediately followed with a ! + digit or end of string.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563