Une façon simple avec re.subn, qui peut également accepter une fonction au lieu d'une chaîne de remplacement:
import re
from random import randint
def select(m):
choices = m.group(1).split('|')
return choices[randint(0, len(choices)-1)]
def spinner(s):
r = re.compile('{([^{}]*)}')
while True:
s, n = r.subn(select, s)
if n == 0: break
return s.strip()
Il remplace simplement tous les choix les plus profonds qu'il rencontre, alors pas d'autre choix que itère reste. subn
renvoie un tuple avec le résultat et le nombre de remplacements effectués, ce qui est pratique pour détecter la fin du traitement.
Ma version de select()
peut être remplacée par celle de Bobince qui utilise random.choice()
et est plus élégante si vous voulez juste coller à un sélecteur aléatoire. Si vous voulez construire un arbre de choix, vous pouvez étendre la fonction ci-dessus, mais vous aurez besoin de variables globales pour garder une trace de l'endroit où vous êtes, donc déplacer les fonctions dans une classe aurait du sens. C'est juste un indice, je ne développerai pas cette idée puisque ce n'était pas vraiment la question orginale.
Notez enfin que vous devez utiliser r.subn(select, s, re.U)
si vous avez besoin de chaînes unicode (s = u"{...}"
)
Exemple:
>>> s = "{{Hello|Hi|Hey} {world|earth} | {Goodbye|farewell} {noobs|n3wbz|n00blets}}"
>>> print spinner(s)
'farewell n3wbz'
Edit: Remplacée sub
par subn
pour éviter boucle infinie (grâce à Bobince pour le signaler) et le rendre plus efficace, et remplacé {([^{}]+)}
par {([^{}]*)}
pour extraire vide cur ly également. Cela devrait le rendre plus robuste aux modèles mal formatés.
Pour les personnes qui aiment mettre autant que possible sur une ligne (que je personnellement n'encouragerais):
def spin(s):
while True:
s, n = re.subn('{([^{}]*)}',
lambda m: random.choice(m.group(1).split("|")),
s)
if n == 0: break
return s.strip()
Comment décidez-vous lequel choisir? Randomness? – strager
Oui par hasard – y2k
Ou s'il y a une manière insensée de trouver par programme toutes les combinaisons qui seraient leet, mais pas nécessaire. – y2k