I\'m trying to extract email addresses from plain text transcripts of emails. I\'ve cobbled together a bit of code to find the addresses themselves, but I don\'t know how to mak
If your goal is actually to extract email addresses from text, you should use a library built for that purpose. Regular expressions are not well suited to match arbitrary email addresses.
But if you're doing this as an exercise to understand regular expressions better, I'd take the approach of expanding the expression you're using to include the extra text you want to match. So first, let me explain what that regex does:
[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}
[\w\-]
matches any "word" character (letter, number, or underscore), or a hyphen[\w\-\.]+
matches (any word character or hyphen or period) one or more times@
matches a literal '@'[\w\-]
matches any word character or hyphen[\w\-\.]+
matches (any word character or hyphen or period) one or more times[a-zA-Z]{1,4}
matches 1, 2, 3, or 4 lowercase or uppercase lettersSo this matches a sequence of a "word" that may contain hyphens or periods but doesn't start with a period, followed by an @
sign, followed by another "word" (same sense as before) that ends with a letter.
Now, to modify this for your purposes, let's add regex parts to match "From", the name, and the angle brackets:
From: [\w\s]+?<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})>
From:
matches the literal text "From: "[\w\s]+?
matches one or more consecutive word characters or space characters. The question mark makes the match non-greedy, so it will match as few characters as possible while still allowing the whole regular expression to match (in this case, it's probably not necessary, but it does make the match more efficient since the thing that comes immediately afterwards is not a word character or space character).<
matches a literal less-than sign (opening angle bracket)m.group(1)
to get the text matched by that part of the regex.>
matches a literal greater-than signSince the regex now uses capturing groups, your code will need to change a little as well:
import re
foundemail = []
mailsrch = re.compile(r'From: [\w\s]+?<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})>')
for line in open("text.txt"):
foundemail.extend([m.group(1) for m in mailsrch.finditer(line)])
print foundemail
The code [m.group(1) for m in mailsrch.finditer(line)]
produces a list out of the first capturing group (remember, that was the part in parentheses) from each match found by the regular expression.