不幸的是,除了 B-Money 的所有建议在大多数情况下都是无效的。
这里有很多有效的电子邮件,例如:
- günter@web.de(德语变音符号)
- антон@россия.рф(俄语,рф 是有效域)
- 中文和许多其他语言(参见例如国际电子邮件和链接规范)。
由于获得正确验证的复杂性,我提出了一个非常通用的解决方案:
<input type="text" pattern="[^@\s]+@[^@\s]+\.[^@\s]+" title="Invalid email address" />
它检查电子邮件是否在“@”之前包含至少一个字符(也包括数字或除另一个“@”或空格之外的任何字符),在“@”之后是否包含至少两个字符(或除另一个“@”或空格之外的任何字符)和一个点之间。这种模式不接受像 lol@company 这样的地址,有时用于内部网络。但如果需要,可以使用这个:
<input type="text" pattern="[^@\s]+@[^@\s]+" title="Invalid email address" />
这两种模式也接受不太有效的电子邮件,例如带有垂直标签的电子邮件。但对我来说已经足够好了。更强大的检查,比如尝试连接到邮件服务器或 ping 域,无论如何都应该在服务器端进行。
顺便说一句,我刚刚编写了 angular 指令(尚未经过良好测试),用于novalidate
基于上述模式的电子邮件验证,以支持 DRY 原则:
.directive('isEmail', ['$compile', '$q', 't', function($compile, $q, t) {
var EMAIL_PATTERN = '^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$';
var EMAIL_REGEXP = new RegExp(EMAIL_PATTERN, 'i');
return {
require: 'ngModel',
link: function(scope, elem, attrs, ngModel){
function validate(value) {
var valid = angular.isUndefined(value)
|| value.length === 0
|| EMAIL_REGEXP.test(value);
ngModel.$setValidity('email', valid);
return valid ? value : undefined;
}
ngModel.$formatters.unshift(validate);
ngModel.$parsers.unshift(validate);
elem.attr('pattern', EMAIL_PATTERN);
elem.attr('title', 'Invalid email address');
}
};
}])
用法:
<input type="text" is-email />
对于 B-Money 的模式,“@”就足够了。但它拒绝两个或多个“@”和所有空格。