1

Just a comment: In a previous question, I need to change the values, from column 0 to 1 or 1 to 0, depending on any value being parsed in the $myVar variable, the solution appended by a user here on stackoverflow was ideal:

$myWords=array(
    array('funny','sad'),
    array('fast','slow'),
    array('beautiful','ugly'),
    array('left','right'),
    array('5','five'),
    array('strong','weak')
);

// prepare values from $myWords for use with strtr()
$replacements=array_combine(array_column($myWords,0),array_column($myWords,1))+
              array_combine(array_column($myWords,1),array_column($myWords,0));
echo strtr($myVar,$replacements);

Inputs/Outputs:

   $myVar='I was beautiful and strong when I was 5 now I\'m ugly and weak';
//outputs: I was ugly and weak when I was five now I'm beautiful and strong

This Question:

But when in cases, do you see arrays with more than one option to make the switch? How to make the system do the exchange for any word among the multiple options, but without running the risk of doing "echo" with the key / word originally presented in $myVar that key / word that called the stock exchange action?

$myWords=array(
    array('funny','sad','very sad','hyper funny'),
    array('fast','slow','faster','very slow'),
    array('beautiful','Studious man','great beauty','very hardworking'),
);

$myVar = 'That man is really fast and very hardworking';

How to make the system choose among other options, but it exclude from the exchange or rand or mt_rand etc ..., the keys responsible for calling the action: fast, hardworking, so as not to run the risk of $myVar not be changed.

Possible expected output:

$myVar = 'That man is really faster and Studious man';

fast must not be replaced by fast and very hardworking must not be replaced by very hardworking.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136

1 Answers1

1

I think this is what you are trying to do...

Check the string for a random selection from each subarray. If there is a match, you want to replace it with any of the other words in the same subarray. If there is no match, just move on to the next subarray.

$myWords=array(
    array('funny','sad','very sad','hyper funny'),
    array('fast','slow','faster','very slow'),
    array('beautiful','Studious man','great beauty','very hardworking'),
);

foreach($myWords as $words){
    // randomize the subarray
    shuffle($words);
    // pipe-together the words and return just one match

if(preg_match('/\b\K'.implode('|',$words).'\b/',$myVar,$out)){ Bad pattern = incorrect use of \b

    if(preg_match('/\K\b(?:'.implode('|',$words).')\b/',$myVar,$out)){
        // generate "replace_pair" from matched word and a random remaining subarray word
        // replace and preserve the new sentence
        $myVar=strtr($myVar,[$out[0]=>current(array_diff($words,$out))]);
    }
}
echo $myVar;

If:

$myVar='That man is really fast and very hardworking';

Then the output could be any of the following and more:

That man is really faster and great beauty
That man is really slow and Studious man
etc...

Effectively, no matter what random replacement happens, the output will never be the same as the input.

Here is the demo link.


This is the preg_match_all() version:

$myWords=array(
    array('funny','sad','very sad','hyper funny'),
    array('fast','slow','faster','very slow'),
    array('beautiful','Studious man','great beauty','very hardworking'),
);

$myVar='The slow epic fail was both sad and funny';

foreach($myWords as $words){
    $replacepairs=[];  // clear array

if(preg_match_all('/\b\K'.implode('|',$words).'\b/',$myVar,$out)){ Bad pattern = incorrect use of \b

    if(preg_match_all('/\K\b(?:'.implode('|',$words).')\b/',$myVar,$out)){  // match all occurences
        foreach($out[0] as $w){
            $remaining=array_diff($words,[$w]);  // find the remaining valid replacment words
            shuffle($remaining);                 // randomize the remaining replacement words
            $replacepairs[$w]=current($remaining);  // pluck first value from remaining words
        }
        $myVar=strtr($myVar,$replacepairs);      // use replacepairs on sentence
    }
}
echo $myVar;

Possible outputs:

The faster epic fail was both hyper funny and hyper funny
The very slow epic fail was both very sad and hyper funny
The fast epic fail was both funny and very sad
etc...

Here is the demo link.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • @ArianeMartinsGomesDoRego Does the solution need to enable multiple replacements within a subarray? Consider this string: `The evening news was both sad and funny.` Do I need to use preg_match_all() to replace `sad` and `funny` or will there only ever be just one matching word in the sentence per subarray? – mickmackusa Jun 02 '17 at 02:30
  • My first method using `preg_match()` only permits one replacement from each subarray. My second method using `preg_match_all()` permits multiple replacments from each subarray. You see `sad` and `funny` exist in the same subarray, but they appear twice in the sentence. The second method replaces both of them. – mickmackusa Jun 02 '17 at 02:58
  • Oh yes, I have now seen your answer, I will already test, Thank you :-) – Ariane Martins Gomes Do Rego Jun 02 '17 at 03:03
  • Perfect! Awesome @mickmackusa, Both solutions will help me a lot, fit them in cases, improve my code, I used 3 functions to do this, and did not do the task well, because the key found in the variable participated in random between keys, being In many cases it was returned back to the variable! Your code is straightforward, clean, much smaller than mine, working better, thanks very much :-) Thankssss. Again. – Ariane Martins Gomes Do Rego Jun 02 '17 at 03:24
  • Alright, thanks a lot for the great help and also tips :-) Cheers :-) – Ariane Martins Gomes Do Rego Jun 02 '17 at 03:36
  • there is a problem, when I was applying in my array with the original values, where there are many more sub-arrays, I realized, that the system will be considering, all the excerpts from the face letter of the word, so that the Sometimes, many smaller words, which have the same letters as the lower ones, enter the process and cut words and generate grammatical errors. – Ariane Martins Gomes Do Rego Jun 02 '17 at 04:26
  • Oh yeah, okay, thanks for answering the previous question, which two others have already answered and works well, I will leave yours as the solution, because you have worked in two. Thanks, but this case here is not resolved because it cuts my words in half and glue others to those cut words. Thank you for your participation. – Ariane Martins Gomes Do Rego Jun 02 '17 at 05:15