I have this string
$s = "red2 blue5 black4 green1 gold3";
I need to order by the number, but can show the numbers. Numbers will always appears at the end of the word. the result should be like:
$s = "green red gold black blue";
Thanks!
CodePudding user response:
Does it always follow this pattern - separated by spaces?
I would break down the problem as such:
I would first start with parsing the string into an array where the key is the number and the value is the word. You can achieve this with a combination of
preg_match_all
andarray_combine
Then you could use
ksort
in order to sort by the keys we set with the previous step.Finally, if you wish to return your result as a string, you could
implode
the resulting array, separating by spaces again.
An example solution could then be:
<?php
$x = "red2 blue5 black4 green1 gold3";
function sortNumberedWords(string $input) {
preg_match_all('/([a-zA-Z] )([0-9] )/', $input, $splitResults);
$combined = array_combine($splitResults[2], $splitResults[1]);
ksort($combined);
return implode(' ', $combined);
}
echo sortNumberedStrings($x);
The regex I'm using here matches two seperate groups (indicated by the brackets):
- The first group is any length of a string of characters
a-z
(or capitalised). Its worth noting this only works on the latin alphabet; it won't match ö, for example. - The second group matches any length of a string of numbers that appears directly after that string of characters.
The results of these matches are stored in $splitResults
, which will be an array of 3 elements:
[0]
A combined list of all the matches.[1]
A list of all the matches of group 1.[2]
A list of all the matches of group 2.
We use array_combine
to then combine these into a single associative array. We wish for group 2 to act as the 'key' and group 1 to act as the 'value'.
Finally, we sort by the key, and then implode it back into a string.
CodePudding user response:
$s = "red2 blue5 black4 green1 gold3";
$a=[];
preg_replace_callback('/[a-z0-9] /',function($m) use (&$a){
$a[(int)ltrim($m[0],'a..z')] = rtrim($m[0],'0..9');
},$s);
ksort($a);
print " Version A: ".implode(' ',$a);
$a=[];
foreach(explode(' ',$s) as $m){
$a[(int)ltrim($m,'a..z')] = rtrim($m,'0..9');
}
ksort($a);
print " Version B: ".implode(' ',$a);
preg_match_all("/([a-z0-9] )/",$s,$m);
foreach($m[1] as $i){
$a[(int)substr($i,-1,1)] = rtrim($i,'0..9');
}
ksort($a);
print " Version C: ".implode(' ',$a);
Use one of them, but also try to understand whats going on here.