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.

2
  • I would probably suggest array_map() with array_reduce(). Commented Jun 2, 2017 at 1:33
  • @mickmackusa Oh, yes, I'm sorry, how silly I was, sorry I need to be reminded to do the right thing. :-) Commented Jun 2, 2017 at 1:50

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

@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?
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.
Oh yes, I have now seen your answer, I will already test, Thank you :-)
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.
Alright, thanks a lot for the great help and also tips :-) Cheers :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.