Convertir, ou unformat, une chaîne de variables (comme le format(), mais en sens inverse) en Python
J'ai cordes de la forme Version 1.4.0\n
et Version 1.15.6\n
, et je voudrais un moyen simple d'extraire les trois numéros d'eux. Je sais que je peux mettre des variables dans une chaîne de caractères avec la méthode de mise en forme; en gros, je veux le faire à l'envers, comme ceci:
# So I know I can do this:
x, y, z = 1, 4, 0
print 'Version {0}.{1}.{2}\n'.format(x,y,z)
# Output is 'Version 1.4.0\n'
# But I'd like to be able to reverse it:
mystr='Version 1.15.6\n'
a, b, c = mystr.unformat('Version {0}.{1}.{2}\n')
# And have the result that a, b, c = 1, 15, 6
Quelqu'un d'autre, j'ai trouvé posé la même question, mais la réponse était spécifique à leur cas particulier: L'utilisation de Python dans la chaîne de format dans le sens inverse pour l'analyse
Une réponse générale (comment faire de la format()
dans le sens inverse) ce serait génial! Une réponse pour mon cas précis serait très utile aussi bien.
- je vois certaines réponses ci-dessous qui sont directement à votre problème. mais la meilleure solution serait d'utiliser des expressions régulières à mon humble avis.
- Cela semble une bonne utilisation pour scanf de style C
Vous devez vous connecter pour publier un commentaire.
Fait le Python ordinaire de l'expression de la bibliothèque déjà fournit la fonctionnalité que vous demandez. Vous avez juste à modifier la syntaxe du modèle légèrement
Comme vous pouvez le voir, vous avez à changer la (des nations unies)les chaînes de format à partir de {0} à (?P<_0>.+). Vous pourriez même avoir besoin d'un décimal par (?P<_0>\d+). En outre, vous avez à s'échapper certains caractères pour les empêcher d'être interprétée comme l'expression rationnelle des caractères spéciaux. Mais cette turm peut être automatisé à nouveau par ex. avec
x,y,z = [int(num) for result in re.findall('(\d+)\.(\d+)\.(\d+)', 'Version 1.15.6\n') for num in result]
x,y,z = [int(num) for num in re.findall('(\d+)\.(\d+)\.(\d+)', 'Version 1.15.6\n')[0]]
Il suffit de construire sur Uche réponse, je cherchais un moyen pour inverser une chaîne de caractères via un modèle avec kwargs. J'ai donc monté la fonction suivante:
Qui fonctionne comme par:
Il y a quelques temps j'ai fait le code ci-dessous qui fait l'inverse de format, mais limitée aux cas dont j'avais besoin.
Et, je n'ai jamais essayé, mais je pense que c'est aussi le but de la
parse bibliothèque
Mon code:
pour votre cas, voici un exemple d'utilisation:
Note le
filter(None,v)
pour supprimer unparsable versions (qui renvoient Aucun). Ici, il n'est pas nécessaire.parse
de la bibliothèque. Pour faire ce travail avec python3, il suffit de changerbasestring
àstr
etdict.iteritems()
àdict.items()
EDIT: voir Aussi cette réponse pour un peu plus d'informations sur
parse
etparmatter
.La pypi paquet
parse
sert ce but bien:Peut être utilisée comme ceci:
Noter que les docs disent la
parse
paquet ne correspond pas EXACTEMENT à émuler les spécification du format mini-langue par défaut; il utilise aussi certains type d'indicateurs spécifiés parre
. De la note spéciale est ques
signifie "espace" par défaut, plutôt que destr
. Ceci peut être facilement modifié pour être compatible avec la spécification de format en changeant le type par défaut pours
àstr
(à l'aide deextra_types
):Ici est une idée conceptuelle pour une modification de la
string.Formatter
intégré en classe à l'aide de laparse
package à ajouterunformat
capacité que j'ai moi-même utilisé:IMPORTANT: le nom de la méthode
parse
est déjà en cours d'utilisation par leFormatter
classe, j'ai donc choisiunformat
à la place pour éviter les conflits.Mise à JOUR: Vous pouvez l'utiliser comme cette - très semblable à la
string.Formateur
classe.Mise en forme (identique à
'{:d} {:d}'.format(1, 2)
):Unformatting:
C'est bien sûr une utilisation très limitée comme indiqué ci-dessus. Cependant, j'ai mis en place un pypi paquet (parmatter - un projet à l'origine pour mon propre usage, mais peut-être que d'autres pourront trouver utile) qui explore quelques idées sur la façon de mettre cette idée à plus de travail utile. Le paquet dépend fortement de ladite
parse
paquet.Ce
vous donnera
int
valeurs poura
,b
etc
En fonction de la façon régulière ou irrégulière, c'est à dire, conforme, votre numéro de version formats, vous pouvez envisager l'utilisation de expressions régulières, mais si ils vont rester dans ce format, je serais favorable à la solution la plus simple si cela fonctionne pour vous.
[]
.Voici une solution dans le cas où vous ne souhaitez pas utiliser l'analyse du module. Il convertit les chaînes de format en expressions régulières avec des groupes nommés. On fait quelques hypothèses (décrit dans la docstring) qui n'avaient pas de problème dans mon cas, mais peut ne pas être d'accord dans le vôtre.