Vojthas
Vojthas

Reputation: 53

php replace {rrggbb} colors in string to color text with <span>

I receive text from a game which uses color embedding in text to color messages, you just use it like this: {ff0000}red text {00ff00}green text

I want to output such string via php and have it properly colored. So the above string turns into this

<span style="color: #ff0000">red text </span><span style="color: #00ff00">green text</span>

I have some ideas about this (like I know that the first match of the color needs to be replaced to <span ..> and any next occurrence needs to be replaced to </span><span ...> to close the previous span tag, and that another span closing tag needs to be added to the end of the string if at least one match was found. I could probably over-complicate this and do this manually with loops and comparing the text, but that would be complicated and probably inefficient.

How could I do that with some regex functions (and possibly a loop) in php?

Upvotes: 1

Views: 514

Answers (2)

Syscall
Syscall

Reputation: 19780

You could try something like this :

$str = '{ff0000}red text {00ff00}green text' ;
$str = preg_replace_callback('~\{([^\}]*)\}([^\{]+)~', function($matches) {
    return '<span style="color:#'.$matches[1].'">'.$matches[2].'</span>' ;
}, $str) ;
echo $str ; 

Outputs:

<span style="color:#ff0000">red text </span><span style="color:#00ff00">green text</span>

Upvotes: 2

revo
revo

Reputation: 48711

It's not HTML parsing at all and RegEx is best suited tool here:

{([a-fA-F0-9]+)}((?>[^{]*{?(?!(?1)}))*)

Breakdown:

{   # Match `{`
    ([a-fA-F0-9]+) # Match and capture hex color code
}   # Match `}`
(   # Capturing group #2
    (?> # Start of a non-capturing group (atomic)
        [^{]*   # Match anything up to a `{`
        {?(?!(?1)}) # Match it if not going to contain a color code
    )*  # As much as possible, end of NCG
)   # End of CG #2

RegEx live demo

PHP code:

$text = <<< 'TXT'
{ff0000}red tex {00ff00}green text
TXT;

echo preg_replace('~{([a-fA-F0-9]+)}((?>[^{]*{?(?!(?1)}))*)~',
        '<span style="color: #$1">$2</span>', $text);

PHP live demo

Upvotes: 3

Related Questions