【问题标题】:Find email addresses in large data stream在大数据流中查找电子邮件地址
【发布时间】:2010-10-06 20:16:32
【问题描述】:

仍未解决:( [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 错误

提前致谢

【问题讨论】:

  • 天哪,10 分钟内两个...见stackoverflow.com/questions/535600
  • 那么你为什么不澄清你原来的问题呢?
  • rubular.com 是个好帮手。
  • 请不要使用正则表达式来解析电子邮件地址。
  • 请提供建设性的建议。如果不是正则表达式,那是什么?

标签: ruby regex email-validation


【解决方案1】:

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

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

制作一个匹配任何“可能是”电子邮件地址的正则表达式,然后接受误报

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

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

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

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

【讨论】:

    【解决方案2】:

    您收到什么样的运行时错误消息?是认为正则表达式无效,还是由于目标字符串太大而中断?

    【讨论】:

    • 与正则表达式无效有关。错误指出“+”或“*”字符无效/无法识别。
    • 我尝试使用 \ 字符来转义它们,但它仍然无法正常工作
    • 我专门尝试了以下代码 string_of_data.match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[az ]{2,})$/i) 其中 string_of_data 是读取的字符串变量,其中包含单词和电子邮件地址的随机混合数据
    • 您可能不想听到“为我工作”,对吧?您可以尝试生成最简单的 string_of_data 和不起作用的正则表达式组合,以及最复杂的有效组合,然后将所有内容粘贴到 gist 或 pastie 上吗?
    • 我尝试使用 monster_data_string = "aa joe@example.com sf" 和 regexp = /([^@\s]+)@((?:[-a -z0-9]+\.)+[az]{2,})/i(我删除了 ^ 和 $)在“try ruby​​!(在您的浏览器中)”中,并且有效。
    【解决方案3】:

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

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

    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">
    

    【讨论】:

      【解决方案4】:

      如果您收到关于 +* 在正则表达式中无效的错误消息,那么您做错了什么。这是 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() 方法,因为它只会找到 first 匹配项。请改用scan()

      【讨论】:

        【解决方案5】:

        看这个……

        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)    
        

        【讨论】:

        • 2015 年在这里。检查 TLD 长度已经过时了
        【解决方案6】:

        更好,

        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)
        

        会给你

        --- - - 乔 - 例子 - .com.au - - 让我冷静一下 - 例子 - .com.au

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-25
          • 2018-03-15
          • 2021-07-14
          • 1970-01-01
          • 2012-10-12
          • 1970-01-01
          相关资源
          最近更新 更多