【问题标题】:rails email validation format and regexrails 电子邮件验证格式和正则表达式
【发布时间】:2014-10-17 15:01:57
【问题描述】:

目前正在学习 Michael Hartl rails 教程

考虑到 Rails 中的以下测试

  test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
  end

  test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
  end

以及以下用于电子邮件格式验证的正则表达式

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }

有人可以向我解释一下关于正则表达式的测试是什么吗?为什么有效的测试只有 user@example.com、USER@foo.COM 等。如果我将另一个元素添加到 USER@EXAMPLE.COM 的 valid_addresses 会怎样。为什么 Michael 特意选择上述 5 个示例电子邮件作为 valid_addresses 和 5 个 invalid_addresses?

如果正则表达式测试所有格式并且只返回一个特定的格式,我们为什么需要测试呢?

【问题讨论】:

  • 不太确定您的问题是什么......测试确保无效电子邮件无效并且使用提供的正则表达式有效电子邮件有效。如果您想知道为什么要进行单元测试,check out this question。
  • 我知道我的问题非常令人困惑,所以我想我只是想逐行了解在这种情况下测试的目的是什么。
  • Michael 提出的测试并不详尽。他挑选了一些有效电子邮件地址和一些无效电子邮件地址的示例,以确保正则表达式能够捕获这些情况。他试图找出在输入无效地址时出现的典型错误,以及仍然有效的异常组合。我们进行测试以确保我们在验证部分输入的正则表达式没有错字。

标签: ruby-on-rails regex testing ruby-on-rails-4 railstutorial.org


【解决方案1】:

让我们分解表达式(记住i 修饰符使其不区分大小写):

\A          (?# anchor to the beginning of the string)
[\w+\-.]+   (?# match 1+ a-z, A-Z, 0-9, +, _, -, or .)
@           (?# match literal @)
[a-z\d\-.]+ (?# match 1+ a-z, 0-9, -, or .)
\.          (?# match literal .)
[a-z]+      (?# match 1+ a-z)
\z          (?# anchor to the absolute end of the string)

这就是教程定义的电子邮件(实际上是much more complicated)。因此作者 Michael Hartl 为“有效”和“无效”(根据上述定义)电子邮件编写了几个测试。

“用户”几乎可以是字母数字或包含_+-.。 “域”可以是字母数字或-.。而“TLD”只能是字母。前 5 封电子邮件使用这些先前规则的许多变体作为“可接受的”电子邮件。最后 5 封电子邮件失败的原因如下:

  • user@example,com - , 无法匹配
  • user_at_foo.org - 没有 @
  • user.name@example. - 在. 之后没有 TLD
  • foo@bar_baz.com - 域不能包含 _
  • foo@bar+baz.com - 域不能包含 +

显然,如果您希望更具体的电子邮件匹配(或不匹配),请将它们添加到测试数组中。如果你的测试失败,你知道你需要更新你的表达式:)

【讨论】:

  • @user3277633 我在回答中略过了一点,但我不会使用上述表达式作为最终解决方案。它非常松散,将包含大量误报以及拒绝一些有效的电子邮件。一些误报:TLDs 至少需要为字符,(子)域不能以句点开头/结束,等等。Check this monster RegEx(注意,我不希望你一定要使用它)。跨度>
【解决方案2】:

我认为尝试习惯正则表达式的最佳方法是尝试不同的正则表达式。如果您尝试使用Rubular.com(如书中推荐)并在正则表达式部分粘贴:\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z。字母i 出现在正则表达式后面的文本框中。然后,如果您在测试字符串部分粘贴电子邮件地址:user@example,com,您会注意到电子邮件地址不匹配,但如果您将逗号替换为点,那么它将匹配。第二个错误的电子邮件地址只是测试是否包含字符@(在这种情况下缺少)。

第三个错误的电子邮件地址测试后缀是否包含 1 个或多个字母。 第 4 次错误的电子邮件地址测试电子邮件地址中 @ 后面没有下划线。 第 5 次错误邮件地址测试邮件地址中 @ 后面没有 + 字符。

正确的电子邮件地址基本上测试相同的东西,但在这些电子邮件地址中,下划线和加号位于电子邮件地址的右侧。它还测试了 USER@foo.COM 电子邮件地址是否保存在 User 模型小写:before_save { self.email = email.downcase } 如果没有发生,它将不是测试中的有效电子邮件地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多