1
votes

Texte au format CSV dans les listes imbriquées pour plusieurs délimiteurs (ignorer la première occurrence)

Mes données ressemblent à ceci

delim=",","-",":"
regexPattern = '|'.join(map(re.escape, delim))
with open('output.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    re.split(regexPattern,data)
    writer.writerows(data)

J'essaie de séparer cette liste imbriquée dans chaque colonne de date, heure, nom d'utilisateur, message.

Maintenant, mes délimiteurs sont

, pour séparer la date,

- pour séparer l'heure,

: pour séparer le nom d'utilisateur et le message

Mais le problème est que si j'utilise : , il divisera également le temps puisque c'est au format XX: XX .

À partir de maintenant, ma première étape est d'obtenir le fractionnement correctement, puis je peux avancer avec la conversion en csv.

Tentative 1 - J'ai essayé de diviser les données directement pendant la lecture, mais rien n'a changé.

delim=",","-",":"
regexPattern = '|'.join(map(re.escape, delim))
data = []
for line in open('/content/drive/My Drive/sample.txt'):
    items = line.rstrip('\r\n').split(regexPattern)   # strip new-line characters and split on column delimiter
    items = [item.strip() for item in items]  # strip extra whitespace off data items
    data.append(items)

Tentative 2 - J'ai essayé de me diviser en écrivant en csv

[['15/09/16, 12:21 pm - User1: Hey'],
 ['15/09/16, 12:22 pm - User2: <Media omitted>'],
 ["15/09/16, 12:22 pm - User2: It's yesterday's work"],
 ['15/09/16, 12:22 pm - User1: Gotta work on it.']]

Cela génère une erreur car split attend une chaîne et j'ai une liste. Je ne sais pas comment atteindre mon objectif principal.

Toute aide est appréciée.


3 commentaires

salut @PirateX avez-vous un cas où les utilisateurs ont - ou , ou ; à tout autre endroit en dehors de ces endroits attendus.


À en juger par son commentaire sur la réponse de Rakesh, il le fait.


Oui, la colonne de message peut ou non avoir l'un des délimiteurs


3 Réponses :


1
votes

C'est un cas parfait pour utiliser des groupes d'expression régulière.

s = '15/09/16, 12:21 pm - User1: Hey'
ms = re.match(r'(\d+/\d+/\d+).+?(\d+:\d+).+-\s(.*):\s(.*)', s)

print(ms.groups()) # ('15/09/16', '12:21', 'User1', 'Hey')

Vous pouvez les rejoindre à la ligne csv.


2 commentaires

L'heure doit être 12:21 et l'utilisateur est également ignoré


@DeveshKumarSingh Oups faute de frappe dans l'expression régulière, corrigé.



3
votes

Utilisez le modèle re.compile(r",|\-|\:\s+")

Ex: final

('15/09/16', '12:21 pm', 'User1', 'Hey')
('15/09/16', '12:22 pm', 'User2', '<Media omitted>')
('15/09/16', '12:22 pm', 'User2', "It's yesterday's work")
('15/09/16', '12:22 pm', 'User1', 'Gotta work on it, what,hello.')


2 commentaires

cela fonctionne bien mais il se divise à nouveau s'il rencontre «,» à nouveau dans la colonne Message. Je veux qu'il ignore le fractionnement dans la colonne des messages


J'ai utilisé maxsplit = 3 pour mon cas d'utilisation. Je pense que cela devrait fonctionner.



2
votes

sans sortie RegEx

[['15/09/16', '12:21 pm', 'User1', 'Hey'],
 ['15/09/16', '12:22 pm', 'User2', '<Media omitted>'],
 ['15/09/16', '12:22 pm', 'User2', "It's yesterday's work"],
 ['15/09/16', '12:22 pm', 'User1', 'Gotta work on it.']]

def parse(item):
    date_time, user_message =  item.split(' - ', 1)
    return [*date_time.split(', '), *user_message.split(': ', 1)]

eggs = [['15/09/16, 12:21 pm - User1: Hey'],
        ['15/09/16, 12:22 pm - User2: <Media omitted>'],
        ["15/09/16, 12:22 pm - User2: It's yesterday's work"],
        ['15/09/16, 12:22 pm - User1: Gotta work on it.']]

spam = [parse(egg[0]) for egg in eggs]
print(spam)
  • le formatage de la sortie est de ma part pour plus de clarté
  • vous devez spécifier explicitement maxsplit comme étant 1


0 commentaires