Bạn không nên cố gắng sử dụng regex để xác thực email. Với các TLD luôn thay đổi, trình xác nhận của bạn không đầy đủ hoặc không chính xác. Thay vào đó, bạn nên tận dụng NSDataDetector
các thư viện của Apple sẽ lấy một chuỗi và thử xem liệu có bất kỳ trường dữ liệu đã biết nào không (email, địa chỉ, ngày, v.v.). SDK của Apple sẽ thực hiện rất nhiều việc cập nhật các TLD và bạn có thể giảm bớt những nỗ lực của họ !! :)
Ngoài ra, nếu iMessage (hoặc bất kỳ trường văn bản nào khác) không nghĩ đó là email, bạn có nên xem xét email không?
Tôi đặt chức năng này trong một NSString
danh mục, vì vậy chuỗi bạn đang kiểm tra là self
.
- (BOOL)isValidEmail {
// Trim whitespace first
NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
if (self && self.length > 0) return NO;
NSError *error = nil;
NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
if (!dataDetector) return NO;
// This string is a valid email only if iOS detects a mailto link out of the full string
NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
if (error) return NO;
return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}
hoặc như một String
phần mở rộng nhanh chóng
extension String {
func isValidEmail() -> Bool {
let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
return false
}
let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))
return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
}
}