skip to Main Content

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!

2

Answers


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

    Login or Signup to reply.
  2. Does it always follow this pattern – separated by spaces?

    I would break down the problem as such:

    1. 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 and array_combine

    2. Then you could use ksort in order to sort by the keys we set with the previous step.

    3. 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):

    1. 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.
    2. 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:

    1. [0] A combined list of all the matches.
    2. [1] A list of all the matches of group 1.
    3. [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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search