I’m writing a short class to extract email addresses from documents. Here is my code so far:
# Class to scrape documents for email addresses
class EmailScraper
EmailRegex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
def EmailScraper.scrape(doc)
email_addresses = []
File.open(doc) do |file|
while line = file.gets
temp = line.scan(EmailRegex)
temp.each do |email_address|
puts email_address
emails_addresses << email_address
end
end
end
return email_addresses
end
end
if EmailScraper.scrape("email_tests.txt").empty?
puts "Empty array"
else
puts EmailScraper.scrape("email_tests.txt")
end
My “email_tests.txt” file looks like so:
example@live.com
another_example90@hotmail.com
example3@diginet.ie
When I run this script, all I get is the “Empty array” printout. However, when I fire up irb and type in the regex above, strings of email addresses match it, and the String.scan function returns an array of all the email addresses in each string. Why is this working in irb and not in my script?
Several things (some already mentioned and expanded upon below):
\zmatches to the end of the string, which with IO#gets will typically include a\ncharacter.\Z(upper case ‘z’) matches the end of the string unless the string ends with a\n, in which case it matches just before.emails_addresses\Aand\Zis fine while the entire line is or is not an email address. You say you’re seeking to extract addresses from documents, however, so I’d consider using\bat each end to extract emails delimited by word boundaries.File.foreach()...rather than the clumsy-lookingFile.open...while...getsthingThere’s a smarter one here: http://www.regular-expressions.info/email.html (clicking on that odd little in-line icon takes you to a piece-by-piece explanation). It’s worth reading the discussion, which points out several potential pitfalls.
Even more mind-bogglingly complex ones may be found here.