2 votes

PHP Obtenir des valeurs d'un tableau/générateur de mots aléatoires/séparer une chaîne de caractères dans un tableau

J'ai une phrase qui doit changer aléatoirement les parties qui sont dans les accolades. La partie importante est que les valeurs à l'intérieur des accolades peuvent changer (vous pourriez y mettre n'importe quel mot), donc

$x = '{Please,|Just|If you can,} make so, that this 

{incredible|cool|simple|important|useless} sentence {fast|correctly|instantly} 

changed randomly every time'; //this is the string that needs to be broken up

Quand j'utilise

$parts = explode('{', $x); 

cela me donne un tableau qui ressemble à ceci

array ([0]=>[1]=>{Please,|Just|If you can,} make so, that this [2]=>incroyable|cool|simple|important|inutile} phrase [3]=>rapidement|correctement|instantanément} changée au hasard à chaque fois)

ce qui ne fonctionne pas.

Ce que j'ai fait, c'est :

 $parts = [

  ['Please,','Just','If you can,'], 

  ['incredible', 'cool','simple','important','useless'],

  ['fast','correctly','instantly'],

];

$p = [];

foreach ($parts as $key => $values) {

  $index = array_rand($values, 1);

  $p[$key] = $values[$index];
}

  $x_one = $p[0] . ' make it so that ' .  $p[1] . ' this sentence

changed ' . $p[2] . ' randomly every time.';

echo $x_one;  

Je dois aller $parts de $x car les mots de la chaîne $x peut changer. Je ne sais pas où aller à partir de là.

4voto

Syscall Points 14338

Vous pouvez utiliser preg_replace_callback() pour attraper la séquence, diviser en utilisant | et renvoie une valeur aléatoire :

$x = '{Please,|Just|If you can,} make so, that this

{incredible|cool|simple|important|useless} sentence {fast|correctly|instantly}

changed randomly every time';

// catch all strings that match with {...}
$str = preg_replace_callback('~\{([^}]+)\}~', function($matches){
    // split using |
    $pos = explode('|', $matches[1]);
    // return random element
    return $pos[array_rand($pos)];
}, $x);

echo $str;

Sorties possibles :

  • Si vous le pouvez, faites en sorte que cette phrase cool soit changée aléatoirement à chaque fois.
  • S'il vous plaît, faites en sorte que cette phrase cool change rapidement et aléatoirement à chaque fois.
  • Si vous pouvez, faites en sorte que cette incroyable phrase rapide change aléatoirement à chaque fois.

Expression régulière :

\{       # { character
 (       # capture group
 [^}]+   # all character until }
 )       # end capture group
\}       # } character

1voto

Les Regex peuvent être extrêmement utiles dans ces cas. Elle est utilisée, par exemple, dans les analyseurs syntaxiques pour trouver les tokens.

Dans ce cas, vous voulez obtenir toutes les sous-chaînes entre accolades. Ceci fait l'affaire :

$matches = array();
preg_match_all('/\{([^}]*)\}/', $x, $matches);
print_r($matches);

Sortie :

Array
(
    [0] => Array
        (
            [0] => {Please,|Just|If you can,}
            [1] => {incredible|cool|simple|important|useless}
            [2] => {fast|correctly|instantly}
        )

    [1] => Array
        (
            [0] => Please,|Just|If you can,
            [1] => incredible|cool|simple|important|useless
            [2] => fast|correctly|instantly
        )
)

L'expression '/\{([^}]*)\}/ signifie :

  • / : il peut s'agir de n'importe quel personnage
  • \{ : début avec accolade de début
  • ([^}]+) tout ce qui n'est pas une accolade de fin (les parenthèses sont utilisées pour isoler l'expression correspondante, c'est pourquoi le résultat est à l'indice 1 d'un tableau).
  • \} : terminer par une accolade de fin
  • / : il doit être identique au premier caractère

En d'autres termes : tout ce qui se trouve entre accolades.

Vous pouvez tester les expressions régulières à https://regex101.com/ ou à https://regexr.com/ .

Mais cela ne suffit pas : vous voulez remplacer ces correspondances. preg_replace peut le faire, mais ce n'est pas non plus suffisant, car il faut aussi appeler une fonction pour sélectionner une sous-chaîne aléatoire. preg_replace_callback peut le faire.

<?php

$x = '{Please,|Just|If you can,} make so, that this 

{incredible|cool|simple|important|useless} sentence {fast|correctly|instantly} 

changed randomly every time';

echo preg_replace_callback(
    '/\{([^\}]+)\}/',
    function ($matches) {
        $options = explode('|', $matches[1]);
        return $options[array_rand($options)];
    },
    $x
);

0voto

Yanis-git Points 4166

Une autre approche peut ressembler à ceci :

    $output = $input = '{Please,|Just|If you can,} make so, that this 

{incredible|cool|simple|important|useless} sentence {fast|correctly|instantly} 

changed randomly every time';

/**
 * Will output
 *  0 => string '{Please,|Just|If you can,}' (length=26)
 * 1 => string '{incredible|cool|simple|important|useless}' (length=42)
 * 2 => string '{fast|correctly|instantly}' (length=26)
 */
preg_match_all('/\{([^}]+)\}/',$input,$m);
foreach ($m[1] as $index => $rotateWord) {
    $words = explode('|',$rotateWord); //Split by pipe each words founds
    $randomWord = $words[rand(0, count($words) - 1)]; // Select random word.
    $output = str_replace($m[0][$index], $randomWord, $output);
}

var_dump($output);

0voto

sevavietl Points 2971

Si les valeurs à l'intérieur des accolades peuvent changer, il est en fait préférable de les extraire du modèle dans des tableaux, comme vous l'avez fait dans la question. Ayant les tableaux de pièces et la chaîne de caractères du modèle, vous pouvez alors utiliser array_map avec strtr :

$parts = [
  '%part1%' => ['Please,','Just','If you can,'], 

  '%part2%' => ['incredible', 'cool','simple','important','useless'],

  '%part3%' => ['fast','correctly','instantly'],
];

$template = '%part1% make so, that this %part2% sentence %part3% changed randomly every time';

$result = strtr($template, array_map(function ($values) {
    return $values[array_rand($values, 1)];
}, $parts));

Voici la démo .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X