Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP replace symbols all possible variants

I have array symbols what I want replace, but I need generate all possibillity

$lt = array(
    'a' => 'ą',
    'e' => 'ę',
    'i' => 'į',
);

For example if I have this string:

tazeki

There can be huge amount of results:

tązeki
tazęki
tązęki
tazekį
tązekį
tazękį
tązękį

My question is what formula use to have all variants ?

like image 318
Wizard Avatar asked Dec 25 '22 22:12

Wizard


1 Answers

This should work for you, easy and simple:

What does this code do?

1. Data part

In the data part I just define the string and the replacement's for the single character with a associative array (search character as key, replacement as value).

2. getReplacements() function

This function get's all combinations of the characters which have to be replaced in this format:

key   = index in the string
value = character

So in this code example the array would look something like this:

Array (
    [0] => Array (
        [1] => a
    )    
    [1] => Array (
        [3] => e
    )   
    [2] => Array (
        [3] => e
        [1] => a
    )    
    [3] => Array (
        [5] => i
    )    
    [4] => Array (
        [5] => i
        [1] => a
    )    
    [5] => Array (
        [5] => i
        [3] => e
    )    
    [6] => Array (
        [5] => i
        [3] => e
        [1] => a
    )

)

As you can see this array holds all combinations of the characters which have to be replaced, in this format:

[0] => Array (
     //^^^^^ The entire sub array is the combination which holds the single characters which will be replaced
    [1] => a
   //^     ^ A single character of the full combination which will be replaced
   //| The index of the character in the string (This is that it also works if you have a character multiple times in your string)
   // e.g. 1 ->  t *a* z e k i
   //            ^  ^  ^ ^ ^ ^
   //            |  |  | | | |
   //            0 *1* 2 3 4 5
)    

So how does it gets all combinations?

Pretty simple I loop through every single character which I want to replace with a foreach loop and then I go through every single combination which I already have and combine it with the character which is currently the value of the foreach loop.

But to get this to work you have to start with a empty array. So as a simple example to see and understand what I mean:

Characters which have to be replaced (Empty array is '[]'): [1, 2, 3]

                               //new combinations for the next iteration
                               |
Character loop for NAN*:

    Combinations:
                  - []         |  -> []

Character loop for 1:

    Combinations:
                  - []    + 1  |  -> [1]    

Character loop for 2:

    Combinations:
                  - []    + 2  |  -> [2]
                  - [1]   + 2  |  -> [1,2]    

Character loop for 3:

    Combinations:
                  - []    + 3  |  -> [3]
                  - [1]   + 3  |  -> [1,3]
                  - [2]   + 3  |  -> [2,3]         
                  - [1,2] + 3  |  -> [1,2,3]    
                               //^ All combinations here

* NAN: not a number

So as you can see there is always: (2^n)-1 combinations in total. Also from this method there is a empty array left in the combination array, so before I return the array I just use array_filter() to remove all empty arrays and array_values() to reindex the entire array.

3. Replacement part

So to get all characters from the string where will build the combinations out of I use this line:

array_intersect(str_split($str), array_keys($replace))

This just get's all coincidences with array_intersect() from the string as array with str_split() and the keys from the replace array with array_keys().

In this code the array which you pass to the getReplacements() function would look something like this:

Array
(
    [1] => a
   //^     ^ The single character which is in the string and also in the replace array
   //| Index in the string from the character
    [3] => e
    [5] => i
)

4. Replace all combinations

At the end you only have to replace all combinations in the source string with the replace array. For this I loop just through every combination and replace every single character in the string from the combination with the matching character from the replace array.

This can be simply done with this line:

$tmp = substr_replace($tmp, $replace[$v], $k, 1);
     //^^^^^^^^^^^^^^       ^^^^^^^^^^^^  ^^  ^ Length of the replacement
     //|                    |             | Index from the string, where it should replace
     //|                    | Get the replaced character to replace it
     //| Replaces every single character one by one in the string 

For more information about substr_replace() see the manual: http://php.net/manual/en/function.substr-replace.php

After this line you just add the replaced string in the result array and rest the string to the source string again.


Code:

<?php

    //data
    $str = "tazeki"; 

    $replace = array(
        'a' => 'ą',
        'e' => 'ę',
        'i' => 'į',
    );


    function getReplacements($array) {

        //initalize array
        $results = [[]];

        //get all combinations
        foreach ($array as $k => $element) {
            foreach ($results as $combination)
                $results[] = [$k => $element] + $combination;
        }

        //return filtered array
        return array_values(array_filter($results));

    }

    //get all combinations to replace
    $combinations = getReplacements(array_intersect(str_split($str), array_keys($replace)));

    //replace all combinations
    foreach($combinations as $word) {
        $tmp = $str;
        foreach($word as $k => $v)
            $tmp = substr_replace($tmp, $replace[$v], $k, 1);
        $result[] = $tmp;
    }

    //print data
    print_r($result);

?>

Output:

Array
(
    [0] => tązeki
    [1] => tazęki
    [2] => tązęki
    [3] => tazekį
    [4] => tązekį
    [5] => tazękį
    [6] => tązękį
)
like image 179
Rizier123 Avatar answered Jan 09 '23 15:01

Rizier123