web-dev-qa-db-fra.com

Extraire les sous-chaînes de courrier électronique d'un document volumineux

J'ai un très gros fichier .txt avec des centaines de milliers d'adresses e-mail dispersées. Ils prennent tous le format:

...<[email protected]>...

Quel est le meilleur moyen de permettre à Python de parcourir l'intégralité du fichier .txt en recherchant toutes les occurrences d'une certaine chaîne @domain, puis d'extraire l'intégralité de l'adresse dans les <...>, et de l'ajouter une liste? Le problème que j'ai est avec la longueur variable d'adresses différentes.

23
user1893148

Ce code extrait les adresses électroniques d'une chaîne. Utilisez-le en lisant ligne par ligne

>>> import re
>>> line = "should we use regex more often? let me know at  [email protected]"
>>> match = re.search(r'[\w\.-]+@[\w\.-]+', line)
>>> match.group(0)
'[email protected]'

Si vous avez plusieurs adresses électroniques, utilisez findall:

>>> line = "should we use regex more often? let me know at  [email protected]"
>>> match = re.findall(r'[\w\.-]+@[\w\.-]+', line)
>>> match
['[email protected]', '[email protected]']

L'expression regex ci-dessus trouve probablement l'adresse e-mail non fausse la plus courante. Si vous voulez être complètement aligné avec le RFC 5322 , vous devez vérifier quelles adresses e-mail respectent les spécifications. Vérifiez this out pour éviter tout bogue dans la recherche d’adresses e-mail correctement. 


Edit: comme suggéré dans un commentaire de @kostek : Dans la chaîne Contact us at [email protected]., mon expression régulière renvoie [email protected]. (avec un point à la fin). Pour éviter cela, utilisez [\w\.,]+@[\w\.,]+\.\w+)

Edit II: une autre amélioration remarquable a été mentionnée dans les commentaires: [\w\.-]+@[\w\.-]+\.\w+ qui capturera également [email protected].

74
0x90

Vous pouvez également utiliser ce qui suit pour trouver toutes les adresses électroniques dans un texte et les imprimer dans un tableau ou chaque email sur une ligne distincte.

import re
line = "why people don't know what regex are? let me know [email protected], [email protected] " \
       "[email protected],[email protected]"
match = re.findall(r'[\w\.-]+@[\w\.-]+', line)
for i in match:
    print(i)

Si vous voulez l'ajouter à une liste, imprimez simplement le "match"

cela va imprimer la liste

print(match)

J'espère que cela t'aides.

7
Stryker

Si vous recherchez un domaine spécifique:

>>> import re
>>> text = "this is an email [email protected], it will be matched, [email protected] will not, and [email protected] will"
>>> match = re.findall(r'[\w-\._\+%]+@test\.com',text) # replace test\.com with the domain you're looking for, adding a backslash before periods
>>> match
['[email protected]', '[email protected]']
4
tehsockz
import re 
txt = 'hello from [email protected] to [email protected] about the meeting @2PM'
email  =re.findall('\S+@\S+',s)
print(email)

Sortie imprimée:

['[email protected]', '[email protected]']
0
ayoub ELMAJJODI
import re
rgx = r'(?:\.?)([\w\-_+#~!$&\'\.]+(?<!\.)(@|[ ]?\(?[ ]?(at|AT)[ ]?\)?[ ]?)(?<!\.)[\w]+[\w\-\.]*\.[a-zA-Z-]{2,3})(?:[^\w])'
matches = re.findall(rgx, text)
get_first_group = lambda y: list(map(lambda x: x[0], y))
emails = get_first_group(matches)

S'il te plaît, ne me déteste pas pour avoir essayé cette fameuse regex. La regex fonctionne pour une partie décente des adresses électroniques indiquées ci-dessous. J'ai principalement utilisé ceci comme base pour les caractères valides d'une adresse email.

 enter image description here

Ne hésitez pas à jouer avec elle ici

J'ai également fait une variante où la regex capture les emails tels que name at example.com

(?:\.?)([\w\-_+#~!$&\'\.]+(?<!\.)(@|[ ]\(?[ ]?(at|AT)[ ]?\)?[ ])(?<!\.)[\w]+[\w\-\.]*\.[a-zA-Z-]{2,3})(?:[^\w])
0
david_adler

Voici une autre approche pour ce problème spécifique, avec une expression rationnelle de emailregex.com :

text = "blabla <[email protected]>><[email protected]> <huhu@fake> bla bla <[email protected]>"

# 1. find all potential email addresses (note: < inside <> is a problem)
matches = re.findall('<\S+?>', text)  # ['<[email protected]>', '<[email protected]>', '<huhu@fake>', '<[email protected]>']

# 2. apply email regex pattern to string inside <>
emails = [ x[1:-1] for x in matches if re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", x[1:-1]) ]
print emails   # ['[email protected]', '[email protected]', '[email protected]']
0
nischi