在大数据流中查找电子邮件地址

时间:2009-02-11 06:28:14

标签: ruby regex email-validation

仍未解决:( [2月11日]

我有一个充满随机数据的大文本文件,想要从中提取所有电子邮件地址。

我想在Ruby中使用这样的伪代码:

monster_data_string = "asfsfsdfsdfsf  sfda **joe@example.com** sdfdsf"
monster_data_string.match(EMAIL_REGEX)

有谁知道我会使用什么Ruby电子邮件正则表达式来实现这个目标?

请记住,我正在寻找 Ruby 的答案。我已经尝试了通过谷歌搜索找到的大量正则表达式,但大多数都会导致Ruby运行时错误,说明“+”和“”这样的字符无效/无法识别。*

我已经尝试过的是:

monster_data_string.match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)

但我收到Ruby错误,指出“+”是无效字符

提前致谢

6 个答案:

答案 0 :(得分:14)

注意这个......

f =  File.open("content.txt")
content = f.read    
r = Regexp.new(/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/)     
emails = content.scan(r).uniq                                    
puts YAML.dump(emails)    

答案 1 :(得分:3)

如果您收到关于+*在正则表达式中无效的错误消息,那么您正在做一些非常错误的事情。这是Ruby中的有效正则表达式,虽然它不是你想要的那个:

/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

首先,如果您尝试从“随机”文本中提取地址,则不希望将正则表达式锚定到行的开头和结尾(^$) 。但是一旦你摆脱了锚点,你的正则表达式将匹配你的测试字符串中的**joe@example.com,我认为你不想要它。来自Regular-Expressions.info的正则表达式做得更好,但请阅读该页面以获取有关调整它以满足您特定需求的提示。

/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i

最后(您可能已经知道这一点),您不希望使用match()方法,因为它只能找到第一个匹配。请改为scan()

答案 2 :(得分:1)

鉴于无法使用正则表达式解析每个有效的电子邮件地址,您有两种选择:

制作一个与尽可能多的有效电子邮件地址匹配的正则表达式,并考虑到一些有效但很少使用的电子邮件地址形式可能会被忽略的事实。

制作正则表达式,匹配任何“可能”是电子邮件地址,然后与误报一起生活

在网页上验证用户注册电子邮件地址时,我使用第二种方法清除明显错误的电子邮件地址

从Ruby Cookbook收集,其中有一个关于电子邮件地址验证的非常好的部分:

valid = '[^ @]+'
/^#{valid}@#{valid}\.#{valid}/

显然有一个由Paul Warren编写的6343字符的Perl正则表达式做得非常出色并且也适用于Ruby,但即使这样也不是万无一失的(我认为它也可能有一些性能影响)。

答案 3 :(得分:1)

您获取了哪种运行时错误消息?它是否将正则表达式视为无效,或者由于目标字符串太大而导致正在崩溃?

答案 4 :(得分:1)

尝试帮助你到达那里(虽然不是很优雅,但我承认):

我认为开始和结束锚点(^和$)没有帮助。您可能还想过滤星号?:

irb(main):001:0> mds = "asfsfsdfsdfsf  sfda **joe@example.com** sdfdsf"
  => "asfsfsdfsdfsf  sfda **joe@example.com** sdfdsf"
irb(main):003:0> mds.match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
  => nil
irb(main):004:0> mds.match(/([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/i)
  => #<MatchData "**joe@example.com" 1:"**joe" 2:"example.com">
irb(main):005:0> mds.match(/([^@\s*]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/i)
  => #<MatchData "joe@example.com" 1:"joe" 2:"example.com">

答案 5 :(得分:0)

更好,

require 'yaml'

content = "asfsfsdfsdfsf  sfda **joe@example.com.au** sdfdsf cool_me@example.com.fr"

r = Regexp.new(/\b([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+?)(\.[a-zA-Z.]*)\b/)     
emails = content.scan(r).uniq                                    
puts YAML.dump(emails)

会给你

    ---
    - - joe
      - example
      - .com.au
    - - cool_me
      - example
      - .com.au