在Ruby中,验证电子邮件地址的最佳/简单方法是什么?

53

在Ruby(服务器端)中,验证电子邮件地址的最佳/简易方法是什么?


1
“验证”是什么意思?保证不会有语法错误?测试已存在的域名?确认存在并响应? - Phrogz
@fabspro,你能解释一下David Sulc的回答有什么问题吗?请不要嘲笑原帖作者。 - Andrew Grimm
@AndrewGrimm 首先,这个问题是一个Ruby语言问题,但被接受的答案是一个Ruby on Rails框架的答案。然后,正如您所看到的,在评论线程中,人们要求澄清提问者对验证的含义(检查语法是否符合RFC标准,测试域是否存在,检查电子邮件地址是否有效),但这些请求被忽略了。此外,尽管在此评论线程中已经链接了三个重复的问题,但仍然提出了这个问题。然后他随机选择一个答案,奖励给一个人给出了一个“胡乱猜测”的答案,希望能满足提问者的愿望。 - fabspro
@fabspro 这个问题标记了Rails,并且谈到了“在服务器端”,所以一个Rails的答案应该是可以的。 - Andrew Grimm
显示剩余4条评论
10个回答

79

这会验证'test.com'吗?对我来说失败了。 - Artem Kalinchuk
1
不,这不是一封电子邮件。 - apneadiving
我的意思是它把它当作一封电子邮件处理。 - Artem Kalinchuk
@ArtemKalinchuk 谢谢您的评论!我已经更新了,现在我依赖于Devise正则表达式来保持DRY。 - apneadiving
3
虽然我认为这个答案不错,但我必须提到Ruby!= Rails。该答案未提供超出ActiveRecord验证范围的解决方案。 - Matei Iorgulescu
显示剩余3条评论

8

在Ruby中?与任何语言一样。

向该地址发送确认电子邮件,并附带一个链接,接收方必须在被视为完全验证之前点击该链接。

即使地址格式完全正确(如加粗文本所示),也可能有许多原因导致其无效(该地址没有实际用户、被垃圾邮件过滤器阻止等)。唯一确定的方法是完成某种类型的端到端交易。


3
正则表达式是一种很好的“垃圾数据拒绝”技术,但它并不是一个完整的解决方案。结合发送验证电子邮件和正则表达式似乎是比较理想的解决方案。 - EnabrenTane
1
这是最好的建议。将输入类型设置为电子邮件,以触发基本标志。除此之外,只需发送确认电子邮件即可。 - Blair Anderson

7
validates :email, presence: true, format: /\w+@\w+\.{1}[a-zA-Z]{2,}/

检查电子邮件字段不为空,并且在“@”之前和之后有一个或多个字符

更具体地说,是在@之前有任意一个或多个单词字符,在@之后和之间有至少一个.后跟至少2个字母的任意一个或多个单词字符


这会导致一个有效的电子邮件地址(如rob@hs-soft.com)无法通过验证。 - Confused Vorlon
是的,这太严格了,我会选择:.+@.+\.{1}.{2,} - zarathustra

6
我知道这是一个旧问题,但我一直在寻找一种简单的方法来完成此操作。我发现了一个名为email_validator gem的东西,它非常简单易用。
作为验证器: validates :my_email_attribute, :email => true 在模型之外进行验证 EmailValidator.valid?('narf@example.com') # boolean 希望这能帮助大家。
祝编码愉快。

4

快捷表单:

 validates :email, :format => /@/

正规表达式中的普通形式:

validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }

Source: Validator Class


4

您可以使用

<%=email_field_tag 'to[]','' ,:placeholder=>"Type an email address",:pattern=>"^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},*[\W]*)+$",:multiple => true%>

2
你会不想在控制器或模型中验证这个吗?如果在HTML中进行验证,那么你只需要发送一个HTTP命令就可以绕过这个检查。 - alex_milhouse

3

由于主要答案的博客网站崩溃了,因此在这里通过nice cachergist 提供了代码片段:

# http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/
class EmailValidator < ActiveModel::EachValidator
  # Domain must be present and have two or more parts.
  def validate_each(record, attribute, value)
    address = Mail::Address.new value
    record.errors[attribute] << (options[:message] || 'is invalid') unless (address.address == value && address.domain && address.__send__(:tree).domain.dot_atom_text.elements.size > 1 rescue false)
  end
end

3
您可以参考https://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_format_of进行操作。
代码如下:

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

该代码用于验证电子邮件格式是否正确。其中,":email"是需要验证的属性名称,"/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i"是用于验证电子邮件格式的正则表达式。正则表达式的具体含义可以参考上述链接。

3
如果您正在使用Rails/Devise - 除了@apneadiving的答案之外 -
validates_format_of :email,:with => Devise::email_regexp

Devise::email_regexp取自config / initializers / devise.rb。
config.email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/

2
发送确认邮件,并且通常我会使用这个验证器... D.R.Y.
# lib/email_validator.rb
class EmailValidator < ActiveModel::EachValidator

  EmailAddress = begin
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
    atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
      '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
    quoted_pair = '\\x5c[\\x00-\\x7f]'
    domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
    quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
    domain_ref = atom
    sub_domain = "(?:#{domain_ref}|#{domain_literal})"
    word = "(?:#{atom}|#{quoted_string})"
    domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
    local_part = "#{word}(?:\\x2e#{word})*"
    addr_spec = "#{local_part}\\x40#{domain}"
    pattern = /\A#{addr_spec}\z/
  end

  def validate_each(record, attribute, value)
    unless value =~ EmailAddress
      record.errors[attribute] << (options[:message] || "is not valid") 
    end
  end

end

在你的模型中
validates :email , :email => true

或者
 validates :email, :presence => true, 
                :length => {:minimum => 3, :maximum => 254},
                :uniqueness => true,
                :email => true

也许不太容易,但您必须编写它一次,并在每次需要时使用。 - andrea
4
你是不是从@apneadiving的网页链接复制了这个内容? - Andrew Grimm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接