Home > Software design >  Php format string with pattern
Php format string with pattern

Time:10-15

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

CodePudding user response:

I would use https://www.php.net/manual/en/function.vsprintf.php do get the result:

$str='qweasdzxc';
$pattern='% % %%%% %%%'; // ['X','X','XXXX','XXX']
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

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