sscanf en Python
Je suis à la recherche d'un équivalent de sscanf()
en Python. Je veux analyser les /proc/net/*
fichiers dans C je pourrais faire quelque chose comme ceci:
int matches = sscanf(
buffer,
"%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
local_addr, &local_port, rem_addr, &rem_port, &inode);
J'ai pensé en premier à utiliser str.split
, toutefois, il ne faut pas se déchirer sur les personnages, mais la sep
chaîne dans son ensemble:
>>> lines = open("/proc/net/dev").readlines()
>>> for l in lines[2:]:
>>> cols = l.split(string.whitespace + ":")
>>> print len(cols)
1
Qui devrait être de retour le 17, comme expliqué ci-dessus.
Est-il un Python équivalent à sscanf
(pas de RÉ), ou une chaîne de fractionnement de la fonction de la bibliothèque standard, qui se fend sur toute une gamme de personnages que je ne suis pas au courant?
- Est-il une raison vous êtes en insistant sur la "pas de nouveau"? Regexes sont l'outil parfait pour ce travail.
- Si vous souhaitez programmer en C, pourquoi ne pas programmer en C? Si vous souhaitez programmer en python, utiliser une expression régulière. Il y a même un truc utile dans la documentation du module re de vous dire comment convertir scanf formats en expressions régulières. docs.python.org/library/re.html#simulating-scanf
- le dernier bit aurait fait une super réponse.
- Je pense qu'il serait mieux de demander/interdire des fonctions de demande/interdire les implémentations. "Je voudrais avoir les chaînes de format de spécifier le type de la variable de sortie, pour les types converti pour moi, et pour revendiquer la mise en forme spécifique de la chaîne d'entrée" plutôt que "pas regex" explique pourquoi vous avez cette préférence. Après tout, si quelqu'un utilise les regex pour construire ce que vous avez voulu, vous l'auriez fait cela, n'est-ce pas?
- wat
- Je pense qu'il serait préférable de dire les propriétés de regex vous voulez éviter plutôt que d'éviter une regex tout à fait. Après tout, la regex est peut-être l'outil le plus approprié pour le travail. Il pourrait être possible que quelqu'un en a fait l'outil que vous recherchez, sauf qu'elle utilise les regex derrière les coulisses. Dans ce cas, j'imagine que vous voulez continuer à utiliser cet outil.
Vous devez vous connecter pour publier un commentaire.
Python n'a pas de
sscanf
équivalent intégré, et la plupart du temps il est en fait beaucoup plus de sens pour analyser l'entrée en travail à la chaîne directement, en utilisant les expressions régulières, ou à l'aide d'un outil d'analyse.Probablement surtout utile pour la traduction C, les gens ont mis en œuvre
sscanf
, comme dans ce module: http://hkn.eecs.berkeley.edu/~dyoo/python/scanf/Dans ce cas particulier, si vous voulez juste pour diviser les données en fonction de plusieurs split personnages,
re.split
est vraiment le bon outil.Il y a aussi le
parse
module.parse()
est conçu pour être à l'opposé deformat()
(la nouvelle chaîne de mise en forme de la fonction en Python 2.6 et supérieur).Quand je suis dans une humeur, j'ai l'habitude d'utiliser zip et interprétations de la liste pour le scanf comme comportement. Comme ceci:
Noter que pour les plus complexes de chaînes de format, vous n'avez besoin d'utiliser des expressions régulières:
Notez également que vous avez besoin de fonctions de conversion pour tous les types que vous voulez convertir. Par exemple, ci-dessus, j'ai utilisé quelque chose comme:
scanf
, maissscanf
.bool("false")
retourneTrue
, car seuls les cordes à vide évaluer àFalse
. Cependant, tout n'est pas perdu, vous pouvez le remplacerbool
avec une fonction personnalisée qui se comporte de la manière que vous souhaitez.int(substring1)
,float(substring2)
,strtobool(substring3)
, etstr(substring4)
, dans l'ordre.Vous pouvez diviser sur une plage de caractères à l'aide de la
re
module.float()
pour l'analyser.r = re.compile(r'[\s:]+')
. (C'est une bonne habitude de mettre des expressions régulières dans premières chaînes de caractères je pense, même si cela ne fait aucune différence dans ce cas.)Vous pouvez analyser avec le module
re
à l'aide de les groupes nommés. Il ne sera pas analyser les sous-chaînes à leurs types de données (par exemple,int
) mais c'est très pratique lors de l'analyse des chaînes.Donné cet exemple de ligne de
/proc/net/tcp
:Un exemple imitant votre sscanf exemple avec la variable peut être:
Il y a un ActiveState recette qui met en œuvre une base de scanf
http://code.activestate.com/recipes/502213-simple-scanf-implementation/
vous pouvez activer les ":" à l'espace, et de faire la distinction.par exemple
pas besoin de regex (pour ce cas)
Upvoted orip de réponse. Je pense qu'il est judicieux conseils d'utilisation module re. Les Kodos application est utile lorsque vous approchez d'un complexe à base de regexp tâche avec Python.
http://kodos.sourceforge.net/home.html
Mise à jour: La documentation Python pour son module regex,
re
, comprend une section sur la simulation de scanf, que j'ai trouvé de plus utile que aucune des réponses ci-dessus.https://docs.python.org/2/library/re.html#simulating-scanf
Si les séparateurs sont ':', vous pouvez répartir ':', et ensuite utiliser x.strip() sur les cordes pour se débarrasser de l'un d'espaces avant ni après. int() ignore les espaces.
Il y a un Python 2 mise en œuvre par odiak.