Myślę, że chodzi Ci o coś takiego:
<?php
$input = '<tag value="100.5 %">foo</tag>';
$translate = function($matches) {
$half = floatval($matches[1]) / 2;
return str_replace($matches[1], $half, $matches[0]);
};
$output = preg_replace_callback(
'/\D(\d{1,3}(\.\d{1,4})?) %?/',
$translate,
$input
);
echo $output, PHP_EOL;
Tylko musisz sobie dopracować wyrażenie regularne.
Skoro robisz przeceny to prawdopodobnie jej wartość będziesz chciał zmieniać, więc lepsza będzie taka funkcja:
<?php
$input = '<tag value="100.5 %">foo</tag>';
function makeReduceCallback(float $reduceValue) {
return function($matches) use ($reduceValue) {
$newPrice = floatval($matches[1]) * $reduceValue;
return str_replace($matches[1], $newPrice, $matches[0]);
};
}
$output = preg_replace_callback(
'/\D(\d{1,3}(\.\d{1,4})?) %?/',
makeReduceCallback(0.5),
$input
);
echo $output, PHP_EOL;