2011-10-04 4 views
0

Je travaille sur un problème de Project Euler (pour le plaisir). Il est livré avec un fichier 46kb txt contenant 1 ligne avec une liste de plus noms dans le format comme celui-ci:Correspondance de chaque mot dans un fichier txt

"MARIA","SUSAN","ANGELA","JACK"... 

Mon plan est d'écrire une méthode pour extraire tous les noms et les ajouter dans une liste Python. L'expression régulière est-elle la meilleure arme pour s'attaquer à ce problème?
J'ai regardé le Python re doc, mais j'ai du mal à trouver la bonne regex.

Répondre

3

Si le format du fichier est comme vous le dites, à savoir

  1. Il est une seule ligne
  2. Le format est comme ceci: "MARIA", "SUSAN", "ANGELA", "JACK"

Ensuite, cela devrait fonctionner:

>>> import csv 
>>> lines = csv.reader(open('words.txt', 'r'), delimiter=',') 
>>> words = lines.next() 
>>> words 
['MARIA', 'SUSAN', 'ANGELA', 'JACK'] 
+0

merci, cela fonctionne parfaitement !!! –

3

Cela ressemble à un format que le module csv serait utile. Alors vous ne devriez écrire aucune regex.

1

Une expression rationnelle fera le travail, mais serait inefficace. Utiliser csv fonctionnerait, mais il pourrait ne pas gérer très bien 5000 cellules dans une seule ligne. À tout le moins, il doit charger le fichier entier et maintenir la liste complète des noms en mémoire (ce qui ne vous pose peut-être pas de problème car c'est une très petite quantité de données). Si vous voulez un itérateur pour les fichiers relativement importants (beaucoup plus que 5 000 noms), une machine d'état fera l'affaire:

def parse_chunks(iter, quote='"', delim=',', escape='\\'): 
    in_quote = False 
    in_escaped = False 

    buffer = '' 

    for chunk in iter: 
     for byte in chunk: 
      if in_escaped: 
       # Done with the escape char, add it to the buffer 
       buffer += byte 
       in_escaped = False    
      elif byte == escape: 
       # The next charachter will be added literally and not parsed 
       in_escaped = True   
      elif in_quote: 
       if byte == quote: 
        in_quote = False 
       else: 
        buffer += byte 
      elif byte == quote: 
       in_quote = True 
      elif byte in (' ', '\n', '\t', '\r'): 
       # Ignore whitespace outside of quotes 
       pass 
      elif byte == delim: 
       # Done with this block of text 
       yield buffer 
       buffer = ''      
      else: 
       buffer += byte 

    if in_quote: 
     raise ValueError('Found unbalanced quote char %r' % quote) 
    elif in_escaped: 
     raise ValueError('Found unbalanced escape char %r' % escape) 

    # Yield the last bit in the buffer 
    yield buffer 

data = r""" 
"MARIA","SUSAN", 
"ANG 
ELA","JACK",,TED,"JOE\"" 
""" 
print list(parse_chunks(data)) 

# ['MARIA', 'SUSAN', 'ANG\nELA', 'JACK', '', 'TED', 'JOE"'] 

# Use a fixed buffer size if you know the file has only one long line or 
# don't care about line parsing 
buffer_size = 4096 
with open('myfile.txt', 'r', buffer_size) as file: 
    for name in parse_chunks(file): 
     print name 
1

Si vous pouvez le faire plus simple, puis le faire plus simple. Pas besoin d'utiliser le module csv. Je ne pense pas que 5000 noms ou 46 Ko suffisent à inquiéter.

names = [] 
f = open("names.txt", "r") 

# In case there is more than one line... 
for line in f.readlines(): 
    names = [x.strip().replace('"', '') for x in line.split(",")] 

print names 
#should print ['name1', ... , ...] 
Questions connexes