preg_replace_callback на стринг между @@

vasilev

Registered
Здравейте,
имам array:

PHP:
Array
(
    [@testvar@] => VAR1
    [@testvar2@] => var2
    [@info@] => This is some description
    [@url@] => url.lan
)

както и текст:

test#test2 = /@url@
test2#@testvar@.test2

опитвам се да заменя тези стойности но нещо не се получава:

PHP:
function stage_vars($source,$words){
    return (preg_replace_callback("'@([0-9a-zA-Z\- ]+)@'si", function($match) use ($words) { 
      if(isset($words[$match])){
        if(is_array($words[$match])){
           echo ($words[$match]);
        } else {
        echo ($words[$match]);
        }
      } else{
        echo ($match);
      }
    },  $source));
  }

ако може малко помощ :)

благодаря
 
ок тоест foreach Array.. str_replace ($key,$val,$string)

има ли по добър и бърз начин е въпроса, защото array може да е голям, стринга и той, да не хаби много ресурси и време..
 
Код:
$array = array(
    '@testvar@' => 'VAR1',
    '@testvar2@' => 'var2',
    '@info@' => 'This is some description',
    '@url@' => 'url.lan'
);

$string = 'test#test2 = /@url@ test2#@testvar@.test2';

$escaped_keys = array_map('preg_quote', array_keys($array), array_fill(0, count($array), '/'));

$pattern = '/(' . implode('|', $escaped_keys) . ')/';

$replace_callback = function($matches) use ($array) {
    $key = $matches[0];
    return isset($array[$key]) ? $array[$key] : $key;
};

// Perform the replacement using preg_replace_callback
$result = preg_replace_callback($pattern, $replace_callback, $string);
 
Или аз не разбирм кода"?
PHP:
<?php

// Define the examples as dynamic strings
$examples = [
    'test#test2 = /@placeholder1@',
    'test2#@placeholder2@.test2'
];

// Initialize an empty array to store the results
$results = [];

// Function to extract placeholder and surrounding text
function extractAndAssign(&$results, $string) {
    // Find all occurrences of placeholders
    if (preg_match_all('/@([^@]+)@/', $string, $placeholders)) {
        foreach ($placeholders[1] as $placeholder) {
            // Remove placeholder from the string to get the surrounding text
            $surroundingText = trim(str_replace("@$placeholder@", '', $string));
            // Assign the surrounding text to the placeholder in the results array
            $results["@$placeholder@"] = $surroundingText;
        }
    }
}

// Process each example
foreach ($examples as $example) {
    extractAndAssign($results, $example);
}

// Print the results
echo "Final array:\n";
print_r($results);

?>
 
Има ли причина ключовете на масива също да съдържат @?

Иначе беше близо с твоята имплементация. Само не знам защо използва echo вместо return. Главно там ти е грешката.

PHP:
<?php

function stage_vars($source,$words){
    return preg_replace_callback("'@([0-9a-zA-Z\- ]+)@'si", function($matches) use ($words) { 
        $match = $matches[0];
        
        $replacement = $match;
        if (array_key_exists($match, $words)) {
            $replacement = sprintf("@%s@", $words[$match]);
            // $replacement = $words[$match];
        }
        
        return $replacement;
    },  $source);
}
  
$array = array(
    '@testvar@' => 'VAR1',
    '@testvar2@' => 'var2',
    '@info@' => 'This is some description',
    '@url@' => 'url.lan'
);

$string = 'test#test2 = /@url@ test2#@testvar@.test2@nana@';

var_dump(stage_vars($string, $array));

Не разбрах дали крайния резултат трябва да задържи @ знака или да го махне. Според това си избери кой от двата варианта искаш да ползваш в if блока.
 
Последно редактирано:
Може би не съм дописал.
@testvar@ трябва да стане VAR1.
Няма как да има повторения от вида @testvar@testvar@ - това са staging параметри които се заменят .. и винаги се пишат с @...@. Затова трябва да се замени целият стринг между @@ заедно с @.
Имам подобен с {..} който няма проблем с preg_replace_callback но явно @ трябва да се ескейпне по някакъв начин

Да , горе не е echo а return.. аз тествах какво ли не :)
Сега тествах горните примери както и този още един път. Оказва се че съм пропуснал _ символ в regex.. тъй като стринга може да има и _ .

PHP:
public static function stage_vars($source,$words){
    return (preg_replace_callback("'@([0-9a-zA-Z\-\_ ]+)@'si", function($match) use ($words) { 
      if(isset($words[$match[0]])){
        if(is_array($words[$match[0]])){
           return ($words[$match[0]]);
        } else {
        return ($words[$match[0]]);
        }
      } else{
        return($match[0]);
      }
    },  $source));
  }


благодаря ! всичко е ок :)
 
Последно редактирано:
Разчисти си кода малко. Не знам каква е тази мания с ограждането на всичко в скоби. Прави кода нечетим. Огражда се само, когато наистина има нужда се огражда. И можеш да разчистиш всичките тези else блокове.

PHP:
if(is_array($words[$match[0]])){
           return ($words[$match[0]]);
        } else {
        return ($words[$match[0]]);
        }

какъв е смисъла от това? Двата случая връщат абсолютно едно и също. Виж моя снипет и само си оправи regex-а.
 
@vasilev Аз само да попитам, strstr не върши ли работа?
PHP:
<?php
$strings = 'test#test2 = /@url@ test2#@testvar@.test2@nana@';
$replaceArray = [
    '@testvar@' => 'VAR1',
    '@testvar2@' => 'var2',
    '@info@' => 'This is some description',
    '@url@' => 'url.lan'
];

$result = strtr($strings, $replaceArray);

print_r($result);

резултата

PHP:
test#test2 = /url.lan test2#VAR1.test2@nana@
 

Back
Горе