I have a series of strings of numbers of different lengths that I need to split into chunks of 2 characters. The last chunk should be 3 characters long, if it would be 1 character long.
For example, 22334455
needs to become 22 33 44 55
, but 2233444
needs to become 22 33 444
.
I have:
implode(" ", str_split($string, 2));
but that returns 22 33 44 4
.
What can I do?
I have thought of:
str_split
returnsimplode
but that seems extremely complicated for something that a human would approach like this:
That's a recursive function and in PHP might perhaps look something like:
$chunks = array();
while(strlen($string) > 3) {
$chunks[] = substr($string, 0, 2);
$string = substr($string, 2);
}
$chunks[] = $string;
implode(" ", $chunks);
But that still seems overly complicated compared to a human who would just evaluate, cut, evaluate, cut, evaluate, not cut
.
Is there a more straightforward, less roundabout way?
You might use a regex to split on:
\S\S\K(?=\S\S)
The regex matches:
\S\S
Match 2 non whitespace characters\K
Forget what is matched so far (this will result in the position to split on)(?=\S\S)
Assert that there are 2 non whitespace characters to the rightIf you only want to match digits, you can use \d
instead of \S
See the matches on regex 101 and a PHP demo
$data = [
"",
"2",
"22",
"223",
"2233",
"22334",
"223344",
"2233444",
"22334455"
];
$pattern = '/\S\S\K(?=\S\S)/';
foreach ($data as $item) {
var_export(preg_split($pattern, $item));
}
Output
array (
0 => '',
)array (
0 => '2',
)array (
0 => '22',
)array (
0 => '223',
)array (
0 => '22',
1 => '33',
)array (
0 => '22',
1 => '334',
)array (
0 => '22',
1 => '33',
2 => '44',
)array (
0 => '22',
1 => '33',
2 => '444',
)array (
0 => '22',
1 => '33',
2 => '44',
3 => '55',
)