Search code examples
phpregexpreg-replacepreg-replace-callback

Convert simple codes to html styles


I am making a script for converting some specific tags to known and valid html like

[b] bold [/b] for <span style="font-weight:bold"> bold</span>

[color=red] red text [/color] for <span style="font-color:red"> red</span>

[fs=15]big font[/fs] for <span style="font-size:15px"> big font</font>

and [link=http://www.gooole.com target=new title=goole] google[/link] to be converted to

<a href="http://www.gooole.com" title="goole">google</a>

and also can mix them like [fs=15] this is big. [color=red] red text[/color] [/fs]

Here is the code that I used-

$str = preg_replace( '/\[b\]/', '<span style="font-weight:bold">', $str );
$str =preg_replace( '/\[\/b\]/', '</span>', $str );
$str= preg_replace( '/\[\/fs\]/', '</span>', $str );
$str= preg_replace( '/\[fs=(.*)\]/', '<span style="font-size:$1px">', $str );

$str= preg_replace( '/\[\/color\]/', '</span>', $str );
$str= preg_replace( '/\[color=(.*)\]/', '<span style="font-color:$1">', $str );

This code works fine if used not nested and also works in nested if tag don't have = attribute. Problem occurs when I use something like this

[fs=15] this is big. [fs=12] this is big.  [/fs] [/fs]

It give me

<span style="font-size:15] this is big. [fs=12px"> this is big. </span> </span>

while it should be

<span style="font-size:15px> this is big. <span style="font-size:12px> this is big. </span> </span>

Its working fine with

[b] hi [i] ok [/i] yes [/b]

Please suggest I don't know much regular expression.


Solution

    1. Since you always replace the closing tags with </span>; include them in a single one.
    2. You can use a hash mapping for matching similar tag structures; like [b], [i] etc. and use the hashed structure in preg_replace_callback
    3. Use ungreedy (or lazy) matching with possibly ignorecase modifier. Also, use some other delimiter than /.

    Try the following code:

    // first deal with closing tags
    $str = preg_replace( '#\[/(color|b|i|fs|so|many|tags|can|go|here)\]#i', '</span>', $str );
    // now some functions; with hashmaps
    function colsize( $m ) {
        $map = [    // or $map = Array(
            'color' => 'color: %s',
            'fs' => 'size: %dpx'
        ];    // or );
        return sprintf( '<span style="font-' . $map[$m[1]] . ';">', $m[2] );
    }
    function emph( $m ) {
        $map = [    // or $map = Array(
            'b' => 'weight: bold',
            'i' => 'style: italic'
        ];    // or );
        return '<span style="font-' . $map[$m[1]] . ';">';
    }
    // using the custom functions from above now
    $str = preg_replace_callback( '@\[(color|fs)=([^\]]+)\]@iU', 'colsize', $str );
    $str = preg_replace_callback( '@\[([bi])\]@i', 'emph', $str );