2010-09-28 3 views
0

Je suis nouveau sur python (et ce site); J'essaye d'écrire un script qui utilisera une expression régulière pour chercher dans un fichier donné pour trouver un nom. Je dois imprimer les différentes façons dont le nom a été capitalisé et combien de fois le nom a été trouvé. Mon code actuel va simplement imprimer mon premier drapeau, puis se bloquer. Je ne sais pas si ma boucle for ou mon exp reg est fausse. Merci pour votre temps!L'expression régulière n'est pas trouvée dans la ligne: l'exécution bloque seulement

import re 
import sys 
if __name__ == '__main__': 
    print "flag" 
    for line in sys.stdin: 
     print(line) 
     name_count = re.search("[snyder]", line, re.I) 
     variation = set(re.search(r"([snyder])", line, re.I)) 
    print "flag2" 
    print len(name_count), variation 
+0

code actuel: 're importation import sys importation de FileInput si __name__ == '__main__': print "drapeau" pour ligne fileinput.input(): variation = re.search (r "" "([s] [n] [y] [d] [e] [r])" "", ligne, re.I) variation d'impression print "flag2" ' Il affichera seulement le dernier" snyder "du fichier, que dois-je utiliser pour contenter toutes les instances de" snyder "dans le fichier? – amazinghorse24

+0

J'ai édité ma réponse, voir si cela vous aide. – eldarerathis

Répondre

4

D'abord, je voudrais dire à jeter un oeil à this thread pour un peu d'informations sur la lecture de stdin (si c'est vraiment ce que vous voulez faire). Deuxièmement, je considérerais simplement l'ouverture du fichier au lieu de lire sys.stdin, soit en utilisant une bibliothèque comme fileinput ou with statement or other file handle.

Ensuite, j'ajouterai que votre expression régulière ne va probablement pas faire ce que vous attendez. L'expression [snyder] est une classe de caractères qui correspond à une répétition de n'importe quel caractère de la classe. En d'autres termes, cela correspondra aux lettres individuelles s, n, y, d, e ou r. Si vous voulez faire correspondre la chaîne littérale snyder alors vous devriez simplement utiliser cela comme votre expression: re.search("snyder", line, re.I). Ou, si vous ne voulez pas de correspondance de sous-chaîne (cas où snyder peut apparaître dans une autre chaîne), vous pouvez essayer l'expression régulière \bsnyder\b.


Modifier re: votre commentaire - Deux choses que je vais dire ici:

1) Alors que [s][n][y][d][e][r] est sémantiquement équivalent à snyder, vous voudrez peut-être envisager d'utiliser ce dernier pour des raisons de lisibilité. Une classe de caractères d'un caractère est équivalente à ce seul caractère (tant qu'il est correctement échappé et ainsi de suite si nécessaire). Le vôtre fonctionnera, donc c'est juste une suggestion/heads-up. 2) Essayez d'utiliser re.findall() à la place de re.search(). Je pense que vous obtiendrez ce que vous voulez avec quelque chose comme:

variations = [] 
for line in fileinput.input(): 
    found = re.findall(r"""snyder""", line, re.I) 
    if len(found) > 0: 
     variations += found 
var_set = set(variations) 
print var_set 
print len(var_set) 

Un exemple de ce que cela va faire:

>>> print sl 
['blah', 'blah', 'what', 'is', 'this', 'BLAh', 'some', 'random', 'bLah', 'text', 'a longer BlaH string', 'a BLAH string with blAH two'] 
>>> li = [] 
>>> for line in sl: 
... m = re.findall("blah", line, re.I) 
... if len(m) > 0: 
...  li += m 
... 
>>> 
>>> print li #Contains all matches 
['blah', 'blah', 'BLAh', 'bLah', 'BlaH', 'BLAH', 'blAH'] 
>>> st = set(li) 
>>> print st #Contains only *unique* matches 
set(['bLah', 'BLAH', 'BLAh', 'BlaH', 'blah', 'blAH']) 
>>> print len(st) 
6 
>>> print len(li) 
7 #1 greater than len(st) because st drops a non-unique match 
3

Il n'est pas suspendu, il attend l'entrée sur stdin! remplacer for line in sys.stdin par quelque chose comme:

import fileinput 

for line in fileinput.input("sample.txt"): 
+0

merci! Cela a fonctionné pour moi. – amazinghorse24

0

Pendant que vous y êtes, changement qui à:

pattern = re.compile('(snyder)') 
[...] 
name_count = pattern.search(line, re.I) 

afin de ne pas recompiler l'expression rationnelle pour chaque ligne du fichier d'entrée.

+1

Python met en cache les regex récemment utilisées, donc vous ne recompilez pas l'expression régulière à chaque fois. Cela pourrait être un cas d'optimisation prématurée. :-) – kindall