You don't need to declare a global
"counter" variable or design a class-based workaround. You can simply use a static variable declaration inside of preg_replace_callback()
's custom function.
Code: (Demo) -- this is the way I would code my own project
$ubbText = <<<TEXT
[b]Hey[/b]
[b]Hello[/b]
TEXT;
echo preg_replace_callback(
"~\[b](.*?)\[/b]~si",
function ($m) {
static $counter = 0;
return '<span class="b">' . (++$counter) . '. ' . $m[1] . '</span>';
},
$ubbText
);
Alternatively, you could avoid the use of a static
declaration and use preg_replace()
because your code logic will not possibly replace replacements (an infinite loop is not possible). To be honest, I don't prefer this technique because it involves iterated preg_
function calls which make one replacement per iteration and the regex engine will need to restart from the beginning of the input string each time.
Code: (Demo)
$counter = 0;
do {
$ubbText = preg_replace(
"~\[b](.*?)\[/b]~si",
'<span class="b">' . (++$counter) . '. $1</span>',
$ubbText,
1,
$count
);
} while ($count);
echo $ubbText;
Output (from both snippets):
<span class="b">1. Hey</span>
<span class="b">2. Hello</span>
p.s. I suppose I should state for the record that your regex pattern will not favorably handle the possibility of nested tags [b] bold [b]re-bold[/b][/b]
. If these types of occurrences are not possible in your application's text, then no worries. There are ways to mitigate this vulnerability, but I will not digress in this post. Search Stack Overflow for this if your application requires it.