替换到位,解析&字符串操作

时间:2010-03-23 15:41:26

标签: php parsing string

我正在尝试替换字符串中的一组字符。该字符串可能有也可能没有任何要更改的数据。字符串的标记方式允许它从一组字符中更改它的颜色。该字符串可以使用一组已定义的字符将其格式重置为默认值。

此设置非常类似于LINUX控制台上用于颜色和其他特殊效果的ECMA-48标准。

一个字符串可以是^0Black^1Red^2Green^3Yellow^4Blue^5Purple^6Cyan^7White生成以下HTML:

<span style="color: #000">Black</span><span style="color: #F00">Red</span><span style="color: #0F0">Green</span><span style="color: #FF0">Yellow</span><span style="color: #00F">Blue</span><span style="color: #F0F">Purple</span><span style="color: #0FF">Cyan</span><span style="color: #FFF">White</span>

另一个字符串(^1Error^8: ^3User Error)也可以产生:

<span style="color: #F00">Error</span>: <span style="color: #FF0">User Error</span>

您可能会注意到该字符串的^8部分会重置字符串中该部分的颜色。

解析这些字符串的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

我会使用preg_replace_callback。由于回调中需要额外的数据,所以将它们放在一个类中是很实际的,如下所示:

class Escaper
{
    function __construct() {
        $this->colors = array(
            0 => "#000",
            1 => "#00F", 
            //etc
        );
    }

    function replace_color($m) {
        list(, $color, $text) = $m;
        return isset($this->colors[$color]) ?
            "<span style='color:{$this->colors[$color]}'>{$text}</span>" :
            $text;
    }

    function apply($text) {
        $text = preg_replace_callback('~\^(\d+)([^^]+)~', array($this, 'replace_color'), $text);
        // more escapes to process?

        return $text;
    }
}

//

 $e = new Escaper; 
 $convertedText = $e->apply($sourceText);

答案 1 :(得分:0)

我创建了str_inject函数,如下所示:

<?php

/* Function Calls */
// Inject one string into another at a specific point.
function str_inject($sourceStr, $injectStr, $injectPos)
{
    if ($injectPos >= strlen($sourceStr)) {
        trigger_error('Inject posisition is greater then the length of the source string, concating string!', E_USER_NOTICE);
        return str_pad($sourceStr, $injectPos) . $injectStr;
    }

    return substr($sourceStr, 0, $injectPos) . $injectStr . substr($sourceStr, $injectPos);
}

/* Example Strings */
#        0123456789012345
$str1 = 'This is a string';
$str2 = ' just';

/* Example Output */
// Example 1: Proper Useage.
$str = str_inject($str1, $str2, 7);
echo $str . PHP_EOL; # echos: 'This is just a string';

// Example 2: Inproper Useage.
$str = str_inject($str1, $str2, 16);
echo $str . PHP_EOL; # echos: 'This is a string just';

// Example 3: Non Hidden, Short Hand, ECMA-48 Colours
# Make ECMA-48 of Strings.
$ecma48 = array();
for ($i = 0; $i < 8; ++$i)
{
    $ecma48[$i] = "\033[3{$i}m";
}
$ecma48[] = "\033[39m"; # Reset Forground Color
$ecma48[] = "\033[0m"; # Reset All

# Setting up Varables
$str = '^1Red^8Reset Color'; # Example String

# Parse str loop
for ($i = 0, $j = 1, $l = strlen($str); $i < $l; ++$i, ++$j)
{
    if ($str{$i} == '^' && is_numeric($str{$j}))
    {
        // Save Δ Change Array Key Number & Δ Len of Replace Str;
        $ΔAKN = $str[$j]; # Δ (Change) Array Key Number;
        $ΔLen = strlen($ecma48[$ΔAKN]); # Δ (Change) Array Value Len. 
        // Remove The Formatting
        $str[$i] = NULL; # Remove ^
        $str[$j] = NULL; # Remove Int.
        // Place ECMA-48 Charaters into String.
        $str = str_inject($str, $ecma48[$ΔAKN], $i);
        // Move Str Pointers Past Δ.
        $i += $ΔLen;
        $j += $ΔLen;
        // And Increase String Size to New Length.
        $l += $ΔLen - 2; # Minus two because we removed the formatting already.
    }
}

# Print results.
echo $str;

?>