2015-04-14 1 views
3

Je ne pourrais pas sembler trouver un fil sur celui-ci, mais il semble que quelque chose qui devrait être assez simple. Im essayant d'utiliser regex pour rechercher une ligne dans une sortie pour un nombre 0-99, et faire une action, mais si le nombre est 100 alors il fera une action différente. Heres ce que j'ai essayé (version simplifiée):Python regex recherche gamme de nombres

OUTPUT = #Some command that will store the output in variable OUTPUT 
OUTPUT = OUTPUT.split('\n') 
for line in OUTPUT: 
    if (re.search(r"Rebuild status: percentage_complete", line)): #searches for the line, regardless of number 
     if (re.search("\d[0-99]", line)): #if any number between 0 and 99 is found 
      print"error" 
     if (re.search("100", line)): #if number 100 is found 
      print"complete" 

Je l'ai essayé et il capte toujours l'erreur 100 et impressions.

Répondre

4

Ce: \d[0-99] signifie un chiffre (\d), suivi d'un numéro (0-9) ou 9. Si vous êtes après la plage numérique de [0-99], vous devez utiliser quelque chose de semblable à \b\d{1,2}\b. Cela correspond à toute valeur numérique composée de 1 ou 2 chiffres.

+0

Oui, j'ai essayé aussi, mais il va toujours imprimer l'erreur quand il trouve un 100 – bladexeon

+3

@bladexeon: Le problème était que 100 était techniquement, une correspondance valide pour cette expression régulière (il correspondrait à la valeur de «10»). J'ai modifié l'expression pour inclure des limites de mot (le 'b)' 'pour faire face à cela. – npinti

+0

Votre approche a eu le plus de sens, mais je ne pouvais pas faire fonctionner les limites. donc à la place j'ai fait: 'si re.search (" \ d {1,2} ", ligne) et non re.search (" 100 ", ligne):' Cela a semblé fonctionner. Merci pour l'aide! – bladexeon

0

0 - 99:

>>> s='\n'.join(["line {} text".format(i) for i in range(-2,101) ]) 
>>> import re 
>>> re.findall(r'(?<!\-)\b(\d\d|\d)\b', s) 
['0', '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', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99'] 

Le regex '(?<!\-)\b(\d\d|\d)\b' correspond à 2 chiffres 0-99 et ne correspond pas à des nombres négatifs tels que

Demo

100 est facile: '(?<!\-)\b100\b'

Si vous ne voulez pas faire correspondre les flotteurs: \b(?<![-.])(\d\d|\d)(?!\.)\b

Demo

3

Vous pouvez simplifier vos regexes en re-commande vos tests numériques, et en utilisant elif au lieu de if sur le test 2 chiffres.

for line in output: 
    if re.search("Rebuild status: percentage_complete", line): 
     if re.search("100", line): 
      print "complete" 
     elif re.search(r"\d{1,2}", line): 
      print "error" 

Le test pour un nombre à 2 chiffres est effectué uniquement si le test pour "100" échoue.

L'utilisation d'une chaîne brute n'est pas strictement nécessaire avec r"\d{1,2}" mais il est recommandé d'utiliser une chaîne brute pour toute expression regex contenant une barre oblique inverse.

Notez que vous n'avez pas besoin de parenthèses autour des conditions en Python, donc les utiliser ajoute un encombrement inutile.


Comme Dawg mentionne dans les commentaires, le test « 100 » peut être resserrée à re.search(r"\b100\b", line), mais ce n'est pas nécessaire si nous pouvons garantir que nous testons que les pourcentages entiers compris entre 0 - 100

+0

Votre approche m'a fait penser à une autre: Match sur '\ d +'. Convertissez le groupe correspondant en 'int' et comparez numériquement plutôt qu'avec regex. Il utilise regex pour ce qu'il est bon, mais traite les nombres comme des nombres plutôt que du texte. –

+0

Cela a également travaillé pour moi, merci! – bladexeon

+0

@StevenRumbalski: Je suppose que ce serait plus efficace, car cela réduit le nombre de recherches regex effectuées. OTOH, nous pourrions remplacer la recherche de "100" avec un simple 'str.find (" 100 ")' ... –