Php format string with pattern

Viewed 483

I have a string (trimmed) and I would like to split this string according to a predefined pattern. I wrote a code which is probably more interpretive.

    $string="123456789";
    $format=['XXX','XX','XXXX'];
    $formatted="";
    foreach ($format as $cluster){
        $formattedCluster=substr($string,0,strlen($cluster));
        $string=substr($string,strlen($cluster));
        $formatted.=$formattedCluster.' ';
    }
    $formatted=substr($formatted, 0, -1);

    dd($formatted);

    //outputs: "123 45 6789"

As you can see it takes a string without any whitespace, and separates it with whitespaces according to a pattern $format in this case. The pattern is an array.

A pseudo example:

$str='qweasdzxc'

$pattern=['X','X','XXXX','XXX']

$formatted='q w easd zxc'; //expected output

It works as expected but it is rather hideous. What is the correct solution to this problem? By correctness, I mean speed and readability.

Environment: Php 7.4, Laravel 8

4 Answers
$string = "qweasdzxc";
$chunks = array(1,1,4,3);
// Optional check to ensure that $string can be divided into requested chunks
if(array_sum($chunks) <> strlen($string)) { 
    echo "String length does not fit requested chunks.";
}
$i=0;
$output = "";
foreach($chunks as $chunk) { 
    $output .= substr($string,$i,$chunk) . " ";
    $i += $chunk;
}

echo rtrim($output);
// Outputs "q w easd zxc"

Probably an easier way to remove the whitespace from the right hand end by not adding it in the first place based on whether or not it's the last element of the array, but that does the trick.

easy way to use preg_match try this.

$data = '11234567890';

if(preg_match( '/^\d(\d{3})(\d{3})(\d{4})$/', $data,  $matches))
{
    $result = $matches[1] . ' ' .$matches[2] . ' ' . $matches[3];
    echo  $result;
}

I don't think it's what you expected but:

function format_number($number) {
    $number_size = strlen($number);
    
    if (9 != $number_size) {
        return $number;
    }
    
    $step     = 0;
    $formated = '';
    foreach (range(0, 9) as $i => $n) {
        if (isset($number[$n])) {
            switch ($step) {
                case 0:
                case 1:
                case 3:
                case 5:
                case 6:
                case 7:
                case 8:
                    $formated .= $number[$n];
                    break;
                case 2:
                case 4:
                    $formated .= $number[$n] . ' ';
                    break;
            }   
            $step++;
        }
    }
    
    return $formated;
}

Working only for the pattern XXX XX XXXX

Related