代码之家  ›  专栏  ›  技术社区  ›  Mark Tomlin

就地替换、解析和字符串操作

  •  0
  • Mark Tomlin  · 技术社区  · 16 年前

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

    这个设置非常类似于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 回复  |  直到 16 年前
        1
  •  3
  •   user187291    16 年前

    我会用 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);
    
        2
  •  0
  •   Mark Tomlin    16 年前

    我创建了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;
    
    ?>
    
    推荐文章