I have a string val of H: 35" V: 24 1/2"
I can extract the 35
and 24
perform a metric conversion calculation then,
(and this is where i'm stuck),
remake the string to look like H: 35" (89 cm) V: 24 1/2" (62 cm)
?
I found regex that could pull the int by
$str = 'H: 35" V: 24 1/2"';
preg_match_all('!\d+!', $str, $matches);
print_r($matches, true);
//Array ( [0] => 35 [1] => 24 [2] => 1 [3] => 2 ) )
But after this, how can I remake the original string and insert the array values after each of the pieces?
FINAL thank you @AbraCadaver for the answer, however I found the fraction 24 1/2
was not getting calculated so here was my final
$str = preg_replace_callback('!(\d+( \d+/\d+)?")!',
function($matches) {
if(isset($matches[2])){
$fraction = $matches[2];
if( strpos( $fraction, '/' ) !== false ) {
$ints = explode('/', $fraction);
$fraction = $ints[0] / $ints[1];
}
}
$new = isset($matches[2]) ? $matches[1] + $fraction : $matches[1];
$new *= 2.54;
return $matches[1] . " (" . round($new) . " cm)" . "<br>";
}
, $str);
I would use preg_replace_callback()
. Just add round()
if needed.
Capture digits \d+
followed by an optional space followed by optional digits / digits ( \d+/\d+)?
and the inch symbol "
:
$str = preg_replace_callback('!(\d+( \d+/\d+)?")!',
function($matches) {
$new = isset($matches[2]) ? $matches[1] + $matches[2] : $matches[1];
$new *= 2.54;
return $matches[1] . " ($new cm)"; //or round($new)
}
, $str);
After seeing the OP's implemented code added to the question, I must post a more refined solution.
Code: (Demo)
$str = 'H: 35" V: 24 1/2"';
$str=preg_replace_callback('~(\d+)(?: (\d+)/(\d+))?"\K~',
function($m){
return ' ('.round(2.54*($m[1]+(isset($m[2])?$m[2]/$m[3]:0))).'cm)';
}
,$str);
echo $str;
Output:
H: 35" (89cm) V: 24 1/2" (62cm)
Calling explode()
as part of your callback functionality means that you designed a sub-optimal regex pattern. All of the components to be processed by the callback with should be individually captured from the start.
Some developers may find my nested arithmetic and function calls in the return
line to be hard to read. These developers may declare single-use variables if they like. Effectively it says:
0
when the fraction substring absent).2.54
.(
and cm)
and return
The \K
at the end of the pattern restarts the fullstring match so that the return value is merely appended to the end of targeted substrings. This avoids the need to copy the capture groups into the return
string.
Here is a Regex Demo of my pattern with the sample input which also provides the pattern explanation in itemized technical terms.