Bonjour,
Je suis actuellement en train de travailler sur un programme PHP permettant de convertir des AVH (ou "visual novels") créée sous Ren'Py. Ce dernier logiciel utilise un langage très proche du Python (j'en avais déjà parlé dans ce post).
Ren'py utilise le code suivant pour faire apparaître un personnage :
Ce qui signifie "montrer Toto à gauche avec l'animation "dissolve".
Code : Sélectionner tout - Visualiser dans une fenêtre à part show Toto at left with dissolve
Il faut donc que je récupère trois arguments :
- l'objet à afficher : Toto
- la position : left
- l'animation : dissolve
Jusqu'ici, tout va bien, je pourrais facilement récupérer les trois arguments grâce aux expressions régulières et la fonction preg_match().
Sauf que ce n'est bien entendu pas si facile (sinon, je ne posterais pas là), vu qu'à part le premier (l'objet à afficher), les arguments sont optionnels et que leur ordre est libre. Les codes suivants sont ainsi tous valides :
Et pour simplifier le tout, il n'y a pas que deux arguments optionnels mais six (with, as, at, behind, onlayer, zorder).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 show Toto show Toto at left show Toto with dissolve show Toto at left with dissolve show Toto with dissolve at left
Pour l'instant, le seul moyen que j'ai trouvé, c'est de faire un strpos pour chaque paramètre, de les classer par ordre d'apparition et de spliter ensuite le tout. Mais cela me semble bien compliqué, peu élégant et assez peu optimisé :
Est-il possible de faire cela grâce à une expression régulière (ou un autre moyen) ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 private function explode_param($string){ $params = array(); // le tableau associatif des paramètres à retourner $positions = array(); // à quel endroit scinder la string $prefixes = array('with', 'as', 'at', 'behind', 'onlayer', 'zorder'); foreach($prefixes as $prefixe) { $pos = strpos($string, ' '.$prefixe.' '); //on ajoute l'espace devant et après pour être sûr de ne pas sélectionner une partie d'un mot if ($pos !== false){ $positions[] = $pos; } } // le paramètre with peut être présent deux fois if(strpos($string, ' with ') != strrpos($string, ' with ')){ // si la dernière occurence est différente de la première $positions[] = strrpos($string, ' with '); } sort($positions); // on classe les arguments par ordre d'apparition foreach($positions as $key=>$pos) { // on isole la chaîne de caractère dédiée à ce paramètre if(isset($positions[$key+1])){ $length = $positions[$key+1] - $pos; $substring = trim(substr($string, $pos, $length)); }else{ $substring = trim(substr($string, $pos)); } // si la chaîne comporte au moins deux mots if(strpos($substring, ' ')!==false){ $nom = strstr($substring, ' ', true); // le nom du paramètre est le premier mot de la chaîne $valeur = strstr($substring, ' '); // la valeur est le reste if($nom=='with' && isset($params[$nom])) $nom .= '2'; // s'il y a deux paramètres with $params[$nom] = $valeur; } } return $params; }
Un peu comme la fonction suivante, mais avec des sous-masques optionnels et non ordonnés :
Merci beaucoup d'avoir pris le temps de lire ce message et peut-être d'y répondre,
Code : Sélectionner tout - Visualiser dans une fenêtre à part preg_match('#^show (?P<nom>\w+) with (?P<transition>\w+) at (?P<position>\w+)#i', $string, $matches)
Korbn, aka Dr Schizo
Partager