The accepted answer suggest using URI::MailTo::EMAIL_REGEXP.
However, this regexp considers 1234@1234 as a valid e-mail address, which is something you probably don't want in a real life app (for instance, AWS SES will throw an exception if you try to send an e-mail to an address like this).
As Darpan points out in the comments, you can simply change the trailing ? in that regexp with +, and it will work as expected. The resulting regex is:
/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\z/
Since the original URI::MailTo regexp, whilst technically valid according to the spec, is imho useless for our needs, we "fix" it in the Devise initializer.
# in config/initializers/devise.rb, put this at the beginning of the file
URI::MailTo.send(:remove_const, :EMAIL_REGEXP)
URI::MailTo.const_set(:EMAIL_REGEXP, /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\z/)
# And then find `config.email_regexp` (it will already be there in the file) and change it to:
config.email_regexp = URI::MailTo::EMAIL_REGEXP
If you're wondering why this monkeypatch isn't put in a separate initializer file, you'd have to name the initializer file as 00_xxx.rb to make it load before the devise initializer. This is against Rails docs recommendations, which actually suggests you use a single initializer for cases like this:
If an initializer has code that relies on code in another initializer, you can combine them into a single initializer instead. This makes the dependencies more explicit, and can help surface new concepts within your application. Rails also supports numbering of initializer file names, but this can lead to file name churn.