Ayrıştırma ve yerinde Değiştir

2 Cevap php

Ben bir dize içinde bir karakter kümesi yerine çalışıyorum. Dize ya da değiştirmek için herhangi bir veri olabilir veya olmayabilir. Dize bu karakter kümesinden o rengini değiştirmek için izin veren bir şekilde yukarı işaretlenir. Dize bu karakter tanımlanmış bir dizi kullanarak varsayılan biçimlendirme oluyor döndürebilirsiniz.

Bu kurulum çok renk ve diğer özel efektler için Linux konsollarında kullanılan ECMA-48 standardına gibi.

Bir dize ^0Black^1Red^2Green^3Yellow^4Blue^5Purple^6Cyan^7White aşağıdaki HTML üretmek nerede olabilir:

<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>

Başka bir dize (^1Error^8: ^3User Error) ayrıca üretmek olabilir:

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

Bunu dizenin ^8 kısım dizenin bu bölümü için rengini sıfırlar fark Nın olabilir.

Dizeleri bu tür ayrıştırma hakkında gitmek için en iyi yolu nedir?

2 Cevap

Ben kullanmak istiyorum preg_replace_callback. Geri arama gerekli ek veri olmadığından, bu gibi bir sınıfta hep birlikte koymak için pratik olacaktır:

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);

Ben aşağıdaki gibi, str_inject fonksiyonu oluşturuldu:

<?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;

?>