2009-12-09 5 views
3

Je rassemble des informations sur certains périphériques Cisco en utilisant python et pexpect, et j'ai eu beaucoup de succès avec les RE pour extraire de petits objets. J'ai peur d'avoir frappé le mur à ce sujet. Certains commutateurs s'empilent ensemble, je l'ai identifié dans le script et utilisé une routine séparée pour analyser les données. Si le commutateur vous est empilé voir les éléments suivants (extrait de la sho ver sortie)Expression régulière python sur plusieurs lignes

Top Assembly Part Number  : 800-25858-06 
Top Assembly Revision Number : A0 
Version ID      : V08 
CLEI Code Number    : COMDE10BRA 
Hardware Board Revision Number : 0x01 


Switch Ports Model    SW Version    SW Image 
------ ----- -----    ----------    ---------- 
* 1 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    2 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    3 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    4 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 


Switch 02 
--------- 
Switch Uptime     : 11 weeks, 2 days, 16 hours, 27 minutes 
Base ethernet MAC Address  : 00:26:52:96:2A:80 
Motherboard assembly number  : 73-9675-15 

Quand je rencontre ce que je dois extraire le numéro commutateur & modèle pour chaque dans le tableau 4, (sw peut être ignoré , mais il peut y avoir entre 1 et 9 commutateurs) C'est la chose de ligne multiple qui m'a eu comme je me suis bien passé avec le reste. Des idées s'il vous plaît?

OK, excuses. Mon regex a simplement commencé à regarder le dernier groupe de - jusqu'à ... alors je ne pouvais pas travailler ou où aller!
- {10] \ s- {10} (+.) Commutateur

Le modèle va changer et le nombre de commutateurs changera, je dois saisir les 4 lignes dans cet exemple qui sont

* 1 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    2 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    3 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    4 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 

mais chaque commutateur pourrait être un modèle différent et il pourrait y avoir entre 1 et 9. pour cet exemple, idéalement je voudrais obtenir

*,1,WS-C3750-48P 
,2,WS-C3750-48P 
,3,WS-C3750-48P 
,4,WS-C3750-48P 

(l'astérisque signifie maître)
mais obtenir ces lignes fixerait m e sur la bonne voie

+2

que diriez-vous de poster le code regex actuel que vous avez essayé ... je ne suis pas sûr que je comprends complètement ce que vous essayez d'obtenir. – Tom

Répondre

2
x="""Top Assembly Part Number  : 800-25858-06 
Top Assembly Revision Number : A0 
Version ID      : V08 
CLEI Code Number    : COMDE10BRA 
Hardware Board Revision Number : 0x01 


Switch Ports Model    SW Version    SW Image 
------ ----- -----    ----------    ---------- 
* 1 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    2 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    3 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 
    4 52  WS-C3750-48P  12.2(35)SE5    C3750-IPBASE-M 


Switch 02 
--------- 
Switch Uptime     : 11 weeks, 2 days, 16 hours, 27 minutes 
Base ethernet MAC Address  : 00:26:52:96:2A:80 
Motherboard assembly number  : 73-9675-15""" 

>>> import re 
>>> re.findall("^\*?\s*(\d)\s*\d+\s*([A-Z\d-]+)",x,re.MULTILINE) 
[('1', 'WS-C3750-48P'), ('2', 'WS-C3750-48P'), ('3', 'WS-C3750-48P'), ('4', 'WS-C3750-48P')] 

MISE À JOUR: parce que la question éditée OP, et Merci Tom d'avoir signalé pour +

>>> re.findall("^(\*?)\s+(\d)\s+\d+\s+([A-Z\d-]+)",x,re.MULTILINE) 
[('*', '1', 'WS-C3750-48P'), ('', '2', 'WS-C3750-48P'), ('', '3', 'WS-C3750-48P'), ('', '4', 'WS-C3750-48P')] 
>>> 
+0

+1 parce que je pense que vous avez fait du bon travail en répondant rapidement à la question :-). Mais pour nettoyer cela ... j'utiliserais \ s + au lieu de \ s *. En outre, re.MULTILINE n'a rien d'important dans ce cas. Je crois que votre solution fonctionnera sans elle :-). – Tom

+0

@Tom, eh bien, vous avez besoin de l'IF multi-ligne qui '^' est pour correspondre au début de la ligne, comme je l'ai expliqué dans ma réponse - je ne suis pas sûr s'il est vraiment nécessaire de synchroniser avec début de ligne, cela dépend de la façon dont le «modèle» peut être identifié. –

+0

Hmm ce que vous faites ci-dessus a l'air correct mais vous ne faites qu'analyser la table.La chaîne que vous utilisez est au milieu d'un tas d'autres textes (voir le message original) avec la table au milieu. Mes données ont peut-être 50 lignes au-dessus et au-dessous – user225882

11

Pour avoir . correspond à tout caractère, y compris une nouvelle ligne, compilez RE avec re.DOTALL parmi les options (rappelez-vous, si vous avez plusieurs options, utilisez |, l'opérateur bit-or, entre eux, afin de les combiner).

Dans ce cas, je ne suis pas sûr que vous avez réellement besoin de ce - pourquoi ne pas quelque chose comme

re.findall(r'(\d+)\s+\d+\s+(WS-\S+)') 

en supposant par exemple que la façon dont vous identifiez un « modèle » est qu'il commence par WS-? Le fait qu'il y aura des sauts de ligne entre un résultat de findall et le prochain n'est pas un problème ici. Pouvez-vous expliquer exactement comment vous identifiez un «modèle» et pourquoi «multiline» est un problème? Peut-être que vous voulez que le re.MULTILINE fasse correspondre ^ à chaque début de ligne, pour saisir vos données avec une référence au début des lignes ...?

+1

Alex, encore une fois, tu m'as battu :-). La clé pour faire des expressions rationnelles multilignes est vraiment le re.DOTALL (ce qui est déroutant parce que vous penseriez que c'est re.MULTILINE). MAIS, comme il l'a souligné, vous n'en avez pas besoin dans ce cas puisque vos données que vous voulez extraire sont sur sa propre ligne :-). En outre, j'aime que alex utilisé \ s +, ce qui signifie 1 ou plusieurs caractères d'espace. Aussi, une chose que j'aurais pu ajouter ... J'aime habituellement nommer mes groupes: (? P WS- \ S +). – Tom

+0

Hmm vous êtes probablement là - va essayer cela et faire rapport, mais comme je suis au Royaume-Uni ce sera demain. Merci beaucoup pour votre temps – user225882

Questions connexes